/Views/_ViewStart.cshtml 文件會在其他視圖文檔被加載之前被載入,代碼如下:
1 @{ 2 Layout = "~/Views/Shared/_Layout.cshtml"; 3 }
標志主板頁為_Layout.cshtml。_ViewStart.cshtml文件同樣可以出現在Views子目錄下,實現不同的控制器下預設載入不同的主版頁面。_Layout.cshtml代碼結構:
1 <header> 2 <div>...</div> 3 </header> 4 <div id="body"> 5 @RenderSection("featured", required: false) 6 <section class="content-wrapper main-content clear-fix"> 7 @RenderBody() 8 </section> 9 </div> 10 <footer> 11 <div>...</div> 12 </footer>
注意代碼中的@RenderSection和@RenderBody,@RenderBody在Razor主版頁面中可以視為“預設坑洞”,也就是說View視圖會被填入到@RenderBody的位置。
@RenderSection在Razor主版頁面中可以被視為“具名坑洞”,如果把required具名參數指定為true的話,那么所有載入這個主版頁面的View頁面都必須在@RenderSection中輸出相應的內容,否則將產生異常。而“featured”就是坑洞的名字,因為required為false,所以不必填充該具名坑洞。MVC模板項目中Index.cshtml是這樣填充的,如下:

1 @section featured { 2 <section class="featured"> 3 <div class="content-wrapper"> 4 <hgroup class="title"> 5 <h1>@ViewBag.Title.</h1> 6 <h2>@ViewBag.Message</h2> 7 </hgroup> 8 <p> 9 To learn more about ASP.NET MVC visit 10 <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. 11 The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET MVC. 12 If you have any questions about ASP.NET MVC visit 13 <a href="http://forums.asp.net/1146.aspx/1?MVC" title="ASP.NET MVC Forum">our forums</a>. 14 </p> 15 </div> 16 </section> 17 }
Razor頁面有固定的執行順序,先執行View在執行Layout主版頁面,因為View與Layout公用一個ViewDataDictionary實體,因此可以通過ViewBag將數據從View傳遞到Layout頁面中,但反過來並不成立。
2,@helper輔助方法
將View頁面中的部分內容或部分代碼抽取出來,變成一個獨立的輔助方法。{不要重復你自己的原則},示例代碼如下:

1 <table> 2 @foreach (var item in Model) 3 { 4 <tr> 5 <td> 6 @GenerateStr(item.ID) 7 </td> 8 <td> 9 @item.Name 10 </td> 11 </tr> 12 } 13 </table> 14 15 @helper GenerateStr(int id) 16 { 17 <text>NO</text>@id 18 }
聲明@Helper輔助方法與C#中聲明方法的方法非常類似,差別就是不用回傳任何類型。
如果要將這個@helper輔助方法用在多個不同的View里,可以將@helper輔助方法獨立出來,放置在根目錄App_Code中。
注:添加App_Code文件夾的方式也很講究,在項目中右鍵-->添加Asp.Net文件夾-->選擇App_Code即可。然后在該文件夾中添加布局文件(cshtml){以習慣取代配置}
然后將之前編寫的@helper方法拷貝進來就可以了。假如說添加了UIHelper.cshtml,並聲明了GenerateStr(int ID)方法,那么會聲明一個UIHelper類,調用方式如下:
@UIHelper.GenerateStr(item.ID)
@helper輔助方法的缺陷:@helper輔助方法只能夠簡單的傳入參數,格式化成想要的樣式輸出,為此Razor提供了@functions自定義函數功能。
先通過@functions定義一個代碼區域,然后把C#代碼寫在里面,如果方法將執行的結果返回給View頁面,則必須以IHtmlString類型返回。示例:

1 @functions{ 2 public IHtmlString GetYesterday() 3 { 4 var theDay = DateTime.Now.AddDays(-1); 5 return new HtmlString(theDay.ToShortDateString()); 6 } 7 }
同樣@functions方法可以用於多個不同的View中共享。不過需要注意,此時應該把@functions中的方法設置為static{靜態方法的使用方式}
3,@using引入命名空間:
1 @using HelloMVC_2.Models 2 @model IEnumerable<HelperTestModel >
注意:在Views目錄中存在web.config文件,<namespaces>區段設置所有View頁面都會引入的命名空間,可以將常用的命名空間添加到這里,如下:

1 <namespaces> 2 <add namespace="System.Web.Mvc" /> 3 <add namespace="System.Web.Mvc.Ajax" /> 4 <add namespace="System.Web.Mvc.Html" /> 5 <add namespace="System.Web.Optimization"/> 6 <add namespace="System.Web.Routing" /> 7 </namespaces>
4,View如何從Action取得數據
使用弱類型取得數據/使用強類型取得數據。前者使用ViewData、ViewBag或TempData,也可以通過@Model屬性,但Model屬性的類型為object,所以是弱型別。
強型別的方式從Controller中取得數據,在View用@model聲明專用類型 如:@model Namespace.MyModel,使用強型別類型的一個好處是,可以使用VS的智能提示的功能。
用ViewData.Model傳遞數據的示例代碼如下:
1 public ActionResult Test() 2 { 3 List<HelperTestModel> list = new List<HelperTestModel>() 4 { 5 new HelperTestModel(){ID=1,Name="Bill"}, 6 new HelperTestModel(){ID=2,Name="Paul"} 7 }; 8 ViewData.Model = list; 9 return View(); 10 } 11 12 @using HelloMVC_2.Models 13 14 @{var temp = (System.Collections.Generic.IEnumerable<HelperTestModel>)Model;} 15 @foreach(var item in temp) 16 { 17 <li>@item.ID</li> 18 }
注意到使用弱類型傳遞至View,改用強型別操作時,需要強制類型轉換。注意@using 引入命名空間的使用。
5,@HTML輔助方法
以@Html.DropDownList()為例,代碼如下:
1 //Controller中代碼示例 2 List<HelperTestModel> list = new List<HelperTestModel>() 3 { 4 new HelperTestModel(){ID=1,Name="Bill"}, 5 new HelperTestModel(){ID=2,Name="Paul"} 6 }; 7 //ViewData.Model = list; 8 ViewData["List"] = new SelectList(list, "ID", "Name"); 9 return View(); 10 //View中代碼示例 11 @Html.DropDownList("List",ViewData["List"] as SelectList)
其中SelectList,是專門提供給項目列表有關的數據類型,如Html.DropDownList()和Html.ListBox()
強類型的輔助方法:在原有名稱上加上For,比如:Html.LabelFor();必須用@model定義View頁面的參考數據模型。示例代碼如下:

1 //Model中 2 public class Product 3 { 4 public int Id { get; set; } 5 [Required] 6 [DisplayName("產品名稱")] 7 public string Name { get; set; } 8 [Required] 9 [DisplayName("產品說明")] 10 public string Description { get; set; } 11 [Required] 12 public int UnitPrice { get; set; } 13 } 14 //View中 15 @model HelloMVC_2.Models.Product 16 17 @using (Html.BeginForm()) 18 { 19 @Html.ValidationSummary(true) 20 <fieldset> 21 <legend>產品資訊</legend> 22 <div class="editor-label"> 23 @Html.LabelFor(model=>model.Name) 24 </div> 25 <div class="efitor-field"> 26 @Html.TextAreaFor(model=>model.Name) 27 @Html.ValidationMessageFor(model=>model.Name) 28 </div> 29 <div class="editor-label"> 30 @Html.LabelFor(model=>model.Description) 31 </div> 32 <div class="efitor-field"> 33 @Html.TextAreaFor(model=>model.Description) 34 @Html.ValidationMessageFor(model=>model.Description) 35 </div> 36 <p> 37 <input type="submit" /> 38 </p> 39 </fieldset> 40 }
效果如圖所示:
通過上面的例子,很容易的實現了關注點分離。
6,使用分部視圖
在ASP.NET Web Form的開發經驗中,對於User Control使用比較頻繁,可以減少重復的代碼{不要重復你自己的原則},利於頁面模塊化,這個概念也被引入了ASP.NET MVC.即“分部視圖”。
分部視圖把部分HTML或邏輯包裝起來,方便重復引用,把分部視圖放置與Views\Shared目錄時,供其他的View載入。
創建部分視圖與創建普通的視圖的的方式一致,特別的是需要選中“創建分部視圖”復選框,並放在Shared目錄下。默認情況下分部視圖*.cshtml為空文檔。
使用分部視圖時,不需要建立相關的Action。因為分部視圖是片段的,必須要選擇一個完整的頁面來載入。用@Html.Partial()方法。
在一個視圖頁面中,如果載入了多個分部視圖,每個分部視圖均可以取到原頁面的ViewData\TempData\Model等數據,也就是說數據可以在各分部視圖之間公用。
分部視圖除了可以直接從檢視頁面載入外,也可以像一般檢視頁面一樣從Controller中使用。示例代碼如下:
1 //控制器中示例代碼 2 public ActionResult Test() 3 { 4 return PartialView(); 5 } 6 //然后創建Test的分部視圖,簡單起見只輸入一行文本 7 8 我的博客是SharpL 9 10 11 //最后在視圖頁面中,通過Html.Action載入TestAction的執行結果 12 @Html.Action("Test")
通過Html.Action與Html.Partial載入分部視圖的結果是一致的,但是過程不同,Html.Action會重新執行一遍Controller的聲明周期。
7,MVC支持兩種不同的“視圖模板”:分別是顯示模板和編輯器模板。
以@Html.EditorFor(m=>m.UserName)來說,@Html.EditorFor模板會依據UserName的類型以及屬性(比如[DataType(DataType.Password)])來找出合適的模板,UserName的數據類型為String,因此模板名稱也將為String,MVC 4中內建的編輯器模板中包括String,所以模板輔助方法會挑出String這個視圖模板來執行。因為模板輔助方法在判斷模板名稱時,除了判斷型別名稱外,還會判斷其屬性,以Password來說,最終將會選擇Password模板來執行。

1 [Required] 2 [DataType(DataType.Password)] 3 [Display(Name = "密碼")] 4 public string Password { get; set; }
MVC4中內建了10個顯示模板,其中包括EmailAddress等。

1 [Required] 2 [MaxLength(200)] 3 [DisplayName("會員電子郵箱")] 4 [DataType(DataType.EmailAddress)] 5 public string Email { get; set; } 6 7 /* 注意Email上的DataType屬性 */ 8 9 10 <div class="display-field"> 11 @Html.DisplayFor(m=>m.Email) 12 </div>
EmailAddress將輸出超鏈接,網頁的HTML源碼碼如下:
1 <div class="display-field"> 2 <a href="mailto:SharpL@qq.com">SharpL@qq.com</a> 3 </div>
8,自定義視圖模板
約定如下:
視圖模板一定要放在指定的幾個規定目錄下{以約定代替配置原則},顯示模板路徑:
/Views/ControllerName/DisplayTemplates或者/Views/Shared/DisplayTemplates目錄下。
編輯器模板位於:
/Views/ControllerName/EditorTemplates或者/Views/Shared/EditorTemplates目錄下。
文檔名稱必須等於類型名稱。文檔的后綴名可以是.cshtml/.vbhtml/.aspx/.ascx。先插入一段代碼,如下:
1 [NotMapped] 2 [UIHint("Gravatar")] 3 [DisplayName("會員Gravatar照片")] 4 public string Gravatar { get; set; }
[NotMapped]屬性指不需要建立在數據庫中,而UIHint屬性指為Gravator添加自定義模板,且模板名稱為”Gravatar“。
於是我們在/Views/Shared/DisplayTemplates文件夾下新建一個”Gravatar.cshtml"文檔,不需要強類型。將該視圖中的@model定義為string,是由其上一級視圖傳遞進來的,代碼如下:

1 @model System.String 2 3 @{ 4 var temp = "算你狠" + Model; 5 } 6 <h2>@temp</h2>
效果如下:
自定義編輯器模板與自定義顯示模板的方式一致,只是約定的路徑不同,示例代碼如下:

1 [Required] 2 [UIHint("DateTime")] 3 [DisplayName("創建會員的日期")] 4 public DateTime CreateOn { get; set; } 5 6 /*注意是EditorFor,如果是LabelFor無效,因為我們修改的是編輯器模板 7 <div class="display-field"> 8 @Html.EditorFor(m=>m.CreateOn) 9 </div> 10 11 /*編輯器模板*/ 12 @model System.DateTime 13 14 @Html.TextBox("",Model.ToString("yyyy/MM/dd"))
9,選用視圖模板的判斷順序:
UIHint屬性優先級最高,屬於自定義模板,其次是DataType,是字段的屬性,最后是字段的類型。
10,@Html.DisplayForModel()
該輔助器方法不用傳入任何參數,每條屬性會挑選出適當的試圖模板來輸出
11,自定義Html輔助方法
也就是給HtmlHrlper類添加拓展方法,將方法定義在抽象類的抽象方法中。

1 public static class ImageHelpers 2 { 3 /// <summary> 4 /// 實際上就是創建一個HtmlHelper類的拓展方法 5 /// </summary> 6 /// <param name="helper">要被拓展的類</param> 7 /// <param name="url">圖片網址啊</param> 8 /// <param name="alternateText">說明文字</param> 9 /// <param name="title">標題文字</param> 10 /// <returns></returns> 11 public static MvcHtmlString Img(this HtmlHelper helper,string url,string alternateText,string title) 12 { 13 return MvcHtmlString.Create(string.Format("<img src='{0}' alt='{1}' title='{2}'/>", url, alternateText, title)); 14 } 15 }
可以以StringBuilder組字串的方式,來寫Html標簽,也可以用TagBuilder來寫,不做詳細的說明,可以參考ASP.NET MVC4開發指南中7.4.5章節的介紹。
12,Url輔助方法
@url.Action("ActionName") 最后輸出結果為 /ControllerName/ActionName
同時@url.RouteUrl(new {name="SharpL"})
還有@Url.Encode("str")等等。
@Url.Content("~/images/Logo.png") 取得網站中靜態文檔的網址路徑。
出處:http://www.cnblogs.com/SharpL/p/4596044.html