【MVC】View的使用


/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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM