跟我學ASP.NET MVC之四:使用Razor
摘要:
視圖引擎處理ASP.NET內容,並查找指令,典型情況是向瀏覽器輸出插入動態內容。MVC框架視圖引擎的名字是Razor。
在本文中,我將帶領讀者快速認識Razor,以後你們看到他們的時候能夠認識它。
工程準備
定義Model
1 namespace Razor.Models 2 { 3 public class Product 4 { 5 public int ProductID { get; set; } 6 public string Name { get; set; } 7 publicstring Description { get; set; } 8 public decimal Price { get; set; } 9 public string Category { set; get; } 10 } 11 }
定義Controller
1 using Razor.Models; 2 using System.Web.Mvc; 3 4 namespace Razor.Controllers 5 { 6 public class HomeController : Controller7 { 8 Product myProduct = new Product 9 { 10 ProductID = 1, 11 Name = "Kayak", 12 Description = "A boat for one person", 13 Category = "Watersports", 14 Price = 275M 15 }; 16 public ActionResult Index()17 { 18 return View(myProduct); 19 } 20 } 21 }
創建Index視圖
1 @model Razor.Models.Product 2 @{ 3 Layout = null; 4 } 5 6 Product Name: @Model.Name
Razor語句以@字符開始。在這個頁面,@model語句聲明了我將傳給視圖action方法的model類型。這讓我能夠通過@Model訪問視圖模型對象的方法、字段和屬性。
運行程序,得到運行結果:
使用Layout
Index.cshtml視圖文件的另一個Razor表達式是:
1 @{ 2 Layout = null; 3 }
這是Razor代碼塊的一個例子,讓我可以在視圖裏面包含C#語句。這個代碼塊以 @{ 開始,以 } 結束。當視圖被渲染的時候語句被執行。
這行代碼設置Layout屬性值為null。在MVC應用程序裏,Razor視圖被編譯到C#類,在基類裏面定義了Layout屬性。設置Layout屬性為null,將告訴MVC框架視圖是自包含的,它將向客戶端提交所有內容。
自包含的視圖在簡單例子程序裏還行,但是一個真實的工程可能含有大量的視圖。Layout是有效的模板,模板中包含應用於整個app的那些標記。以保證正確的JavaScript庫被包含進來,或者保持一致的頁面布局。
創建_BasicLayout.cshtml
1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta name="viewport" content="width=device-width" /> 6 <title>@ViewBag.Title</title> 7 </head> 8 <body> 9 <h1>Product Information</h1> 10 <div style="padding: 20px; border: solid medium black; font-size:20pt"> 11 @RenderBody() 12 </div> 13 <h2>Visit <a href="http://apress.com">Apress</a></h2> 14 </body> 15 </html>
Layout是一種特殊的視圖。
@RenderBody()方法在layout標記中插入action方法得到的視圖內容。
@ViewBag.Title設置頁面標題。
使用layout的視圖將呈現layout視圖中所有的元素,這也是layout是重要模板的原因。
改變Index.cshtml使用Layout:
1 @model Razor.Models.Product 2 @{ 3 Layout = Url.Content("~/Views/_BasicLayout.cshtml"); 4 } 5 6 @{ 7 ViewBag.Title = "Product Name"; 8 } 9 10 Product Name: @Model.Name
Url.Content方法,得到視圖的url路徑字符串,賦值給Layout屬性。
ViewBag.Title = "Product Name";給ViewBag.Title動態屬性賦值,Layout頁面的title標記上顯示這個值。
運行程序,得到運行結果:
使用_ViewStart.cshtml文件
如果沒有_ViewStart.cshtml文件,我將要給所有的視圖都指定layout文件。_ViewStart.cshtml將在所有視圖(如果沒有指定Layout屬性值)呈現之前執行。
_ViewStart.cshtml文件代碼:
1 @{ 2 Layout = Url.Content("~/Views/_BasicLayout.cshtml"); 3 }
修改Index.cshtml文件,刪除代碼行
Layout = Url.Content("~/Views/_BasicLayout.cshtml");
1 @model Razor.Models.Product 2 3 4 @{ 5 ViewBag.Title = "Product Name"; 6 } 7 8 Product Name: @Model.Name
運行程序,將得到上面一樣的結果。
使用Razor表達式
在HomeController裏創建DemoExpression方法:
1 public ActionResult DemoExpression() 2 { 3 ViewBag.ProductCount = 0; 4 ViewBag.ExpressShip = true; 5 ViewBag.ApplyDiscount = false; 6 ViewBag.Supplier = null; 7 return View(myProduct); 8 }
添加DemoExpression視圖:
1 @model Razor.Models.Product 2 3 @{ 4 ViewBag.Title = "DemoExpression"; 5 } 6 7 8 <table> 9 <thead> 10 <tr><th>Property</th><th>Value</th></tr> 11 </thead> 12 <tbody> 13 <tr><td>Name</td><td>@Model.Name</td></tr> 14 <tr><td>Price</td><td>@Model.Price</td></tr> 15 <tr><td>Stock Level</td><td>@ViewBag.ProductCount</td></tr> 16 </tbody> 17 </table>
運行程序,得到運行結果:
View視圖不但能夠通過@Model呈現傳給View方法model定義的類型的對象,還可以使用ViewBag呈現ViewBag的動態屬性。
使用條件語句
在視圖裏還可以包含C#語句。修改視圖代碼:
1 @model Razor.Models.Product 2 3 @{ 4 ViewBag.Title = "DemoExpression"; 5 } 6 7 <table> 8 <thead> 9 <tr><th>Property</th><th>Value</th></tr> 10 </thead> 11 <tbody> 12 <tr><td>Name</td><td>@Model.Name</td></tr> 13 <tr><td>Price</td><td>@Model.Price</td></tr> 14 <tr><td>Stock Level</td> 15 <td> 16 @switch ((int)ViewBag.ProductCount) 17 { 18 case 0: 19 @: Out of Stock 20 break; 21 case 1: 22 <b>Low Stock (@ViewBag.ProductCount)</b> 23 break; 24 default: 25 @ViewBag.ProductCount 26 break; 27 } 28 </td> 29 </tr> 30 </tbody> 31 </table> 32 <div data-discount="@ViewBag.ApplyDiscount" dataexpress="@ViewBag.ExpressShip" data-supplier="@ViewBag.Supplier"> 33 The containing element has data attributes 34 </div>
運行程序,得到運行結果:
以@字符開頭開始一個C#代碼塊,在這個例子裏是@switch。以字符 } 結束一個C#代碼塊,就像你寫常規C#代碼塊一樣。
在Razor代碼塊裏,你可以包含HTML元素以及數據值,就像你在寫HTML代碼和Razor表達式一樣。
例如:
<b>Low Stock (@ViewBag.ProductCount)</b>
@ViewBag.ProductCount
遍歷數組和集合
當寫MVC應用時,你將會經常遍歷數組的內容,或者遍歷一些集合的對象,來呈現它們的內容。
在HomeController類裏添加DemoArray方法:
1 public ActionResult DemoArray() 2 { 3 Product[] array = { 4 new Product {Name = "Kayak", Price = 275M}, 5 new Product {Name = "Lifejacket", Price = 48.95M}, 6 new Product {Name = "Soccer ball", Price = 19.50M}, 7 new Product {Name = "Corner flag", Price = 34.95M} 8 }; 9 return View(array); 10 }
為DemoArray方法添加視圖:
1 @model Razor.Models.Product[] 2 3 @{ 4 ViewBag.Title = "DemoArray"; 5 } 6 7 @if (Model.Length > 0) 8 { 9 <table> 10 <thead><tr><th>Product</th><th>Price</th></tr></thead> 11 <tbody> 12 @foreach (Razor.Models.Product p in Model) 13 { 14 <tr> 15 <td>@p.Name</td> 16 <td>[email protected]</td> 17 </tr> 18 } 19 </tbody> 20 </table> 21 } 22 else { 23 <h2>No product data</h2> 24 }
- @model Razor.Models.Product[]指定這個視圖的模型是Razor.Models.Product數組。
- @if(Model.Length > 0)是 @ 開始的C#代碼塊,Model.Length使用Model訪問傳給視圖的數組長度。
- @foreach (Razor.Models.Product p in Model)遍歷Model表示的數組。
運行程序得到運行結果:
這個視圖還可以使用using namespace語句進行改進:
1 @using Razor.Models 2 @model Razor.Models.Product[] 3 4 @{ 5 ViewBag.Title = "DemoArray"; 6 } 7 8 @if (Model.Length > 0) 9 { 10 <table> 11 <thead><tr><th>Product</th><th>Price</th></tr></thead> 12 <tbody> 13 @foreach (Product p in Model) 14 { 15 <tr> 16 <td>@p.Name</td> 17 <td>[email protected]</td> 18 </tr> 19 } 20 </tbody> 21 </table> 22 } 23 else { 24 <h2>No product data</h2> 25 }
改進後,不需要在Product類型上指定名稱空間了。
跟我學ASP.NET MVC之四:使用Razor