在上一篇中咱們描述了應用於Model上面的各類用於顯示控制的特性類,在本篇中將詳細的介紹這些特性類的應用,雖然它們跟Model元數據的直接關係並不大,可是咱們能夠用它們在編碼階段控制運行時的顯示。html
什麼是Model元數據?編程
生成Model元數據的過程【一】c#
生成Model元數據的過程【二】框架
ModelMetaData的定義、詳解ide
Model元數據應用(經常使用特性應用)-1函數
Model元數據應用(自定義視圖模板)-2學習
Model元數據應用(IMetadataAware接口使用)-3測試
所用示例:編碼
代碼1-1spa
public class Customer { public string CustomerID { get; set; } public string Name { get; set; } public DateTime RegistrationDate{ get; set; } public Address Address { get; set; } } public class Address { public string AddressName { get; set; } }
這是下面所要用的示例Model,下面的代碼1-2示例是使用自定義模型綁定器用於獲取Model數據的,你們只須要看數據的值就好了,對於Model綁定部分後續的篇幅的中再介紹。
代碼1-2
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { return new Customer() { CustomerID = "010", Name = "測試人員", RegistrationDate = DateTime.Now, Address = new Address() { AddressName = "天空之城" } }; }
HiddenInputAttribute類型所表示的意思是將應用的屬性顯示爲隱藏輸入域類型(Hidden),其中包含一個屬性DisplayValue表示是否顯示這個隱藏的輸入域,咱們修改一下代碼1-1中的內容:
代碼1-3
[HiddenInput(DisplayValue=true)] public string CustomerID { get; set; }
而後看一下咱們在視圖界面的代碼:
代碼1-4
@model ConsoleApplication2.Customer @{ ViewBag.Title = "Show"; } <h2>Show</h2> <p>@Html.EditorForModel()</p>
結果如圖1.
圖1
在圖1中咱們看到CustomerID對應的屬性值“010”在頁面裏顯示爲只讀的文本狀態,生成的Html代碼以下:
<input name="CustomerID" id="CustomerID" type="hidden" value="010"/>
修改代碼1-3中的DisplayValue屬性值爲true後,視圖部分的代碼不變,運行結果如圖2。
圖2
在圖2中,已經看不到CustomerID屬性所表示的項了,看到這裏相信咱們已經瞭解了HiddenInputAttribute類型的使用了吧。
看上面的圖2 ,RegistrationDate屬性所對應的值都是日期時間格式的,那怎麼控制屬性值的輸入樣式呢?好比說想讓屬性值顯示爲日期類型,來看代碼1-5
代碼1-5
[DataType(DataType.Date)] public DateTime RegistrationDate{ get; set; }
視圖部分的代碼不用改變來看一下結果圖3
圖3
從上圖中看出輸出值的格式樣式已經改變了。
DisplayAttribute類型用於指示的屬性所顯示的標籤值的修改,好比說圖3中的Name和RegistrationDate,想顯示咱們成咱們自定義的名稱就要用DisplayAttribute類型,來看代碼1-6.
代碼1-6
[Display(Name="姓名")] public string Name { get; set; } [DataType(DataType.Date)] [Display(Name="註冊日期")] public DateTime RegistrationDate{ get; set; }
視圖部分的代碼依舊不變,咱們來看一下運行的結果圖4。
圖4
從圖4咱們已經看到更改了
本小節對視圖模板和UIHintAttribute類型的使用作一些簡單的介紹。
視圖模板是什麼意思呢?就是根據Model元數據提供的信息生成爲指定的視圖模板所對應的Html代碼(包含Html元素樣式),咱們看一下示例,這樣比較直觀。
代碼2-1
public class Customer { [HiddenInput(DisplayValue=false)] public string CustomerID { get; set; } [Display(Name="姓名")] [UIHint("Password")] public string Name { get; set; } [DataType(DataType.Date)] [Display(Name="註冊日期")] public DateTime RegistrationDate{ get; set; } public Address Address { get; set; } }
從代碼2-1中的Name屬性上看到UIHintAttribute類型的特性,使用它的意思就是指定一個視圖模板來爲這個屬性生成Html代碼,這樣爲了直觀的能夠看出來因此使用了Password視圖模板,這個Password視圖模板的意思講Model元數據所對應的屬性值生成爲一個單行的文本框Input元素,而且元素中的字符是不可見的,是可編輯的。看一下結果圖5.
圖5
所對應的Html代碼2-2
代碼2-2
<input name="Name" class="text-box single-line password" id="Name" type="password" value="測試人員"/>
系統爲咱們提供了許多視圖模板,可是也不能亂用的,要保持使用的視圖模板所需類型和指定的屬性一致的。
細心的朋友可能會發如今上面的顯示頁面中都沒有發現Address屬性的值,這個在前篇就強調過,由於Address屬性對應的類型在生成Model元數據的時候被判別爲複雜類型,而模板視圖輔助器是不會去對複雜類型進行處理的,那咱們要怎麼顯示Address屬性中的值呢?
咱們使用自定義的視圖模板,固然做用不止這麼一點,只是用來說解而已。
首先項目中的/Views/Shared的目錄下新建一個名爲EditorTemplates的文件夾,而後在此文件夾中新建一個強類型的分佈視圖文件,類型是指定屬性對應的類型,而且命名視圖文件爲指定屬性的類型名稱,按照示例來講就是Address類型的名稱就是Address,完成後應該是這樣的,圖6
圖6
在此視圖中添加如代碼2-3。
代碼2-3
<p> @Html.LabelFor(m=>m.AddressName) @Html.EditorFor(m => m.AddressName) </p>
而後修改代碼2-1中的Address屬性,而且修改Address類型裏的AddressName屬性要顯示的名稱,用咱們上面講過的DisplayAttribute類型示例代碼2-4
代碼2-4
public class Customer { [HiddenInput(DisplayValue=false)] public string CustomerID { get; set; } [Display(Name="姓名")] [UIHint("Password")] public string Name { get; set; } [DataType(DataType.Date)] [Display(Name="註冊日期")] public DateTime RegistrationDate{ get; set; } [UIHint("Address")] public Address Address { get; set; } } public class Address { [Display(Name="地址名稱")] public string AddressName { get; set; } }
而後再修改掉咱們主視圖頁面的代碼,使用EditFor輔助器單獨的對Address屬性進行處理操做,如代碼2-5所示。
代碼2-5
@model ConsoleApplication2.Customer @{ ViewBag.Title = "Show"; } <h2>Show</h2> <p>@Html.EditorForModel()</p> <p>@Html.EditorFor(m=>Model.Address)</p>
而後咱們看一下修改後的結果圖7.
圖7
還有一些其餘的特性類型的使用示例會在之後修改本篇,如今本人也不是太熟不能亂寫的。
前面的篇幅對Model元數據的生成的詳細過程以及使用都有所粗略的講解,想必這時你們已經對Model元數據有所瞭解了,這個小節介紹如何使用IMetadataAware接口類型來實現咱們直接操做Model元數據,從而跳過那些使用系統自帶的那些特性類,它們是能夠先設置,可是咱們也能夠自定義的設置Model元數據的值,好了廢話很少說了往下看吧。
在Model元數據(二)的篇幅裏,咱們提到過的內容中,在Model元數據生成後的最後一步過程是會調用Model元數據生成提供程序中的一個函數,在此函數中MVC框架會檢索當前Model元數據所指定的類型上的全部特性類型集合,檢索出實現了IMetadataAware接口的特性類,而後使用這個實現類型對當前Model元數據進行操做。可能朋友們看個人這段敘述有點模糊,那咱們直接來看示例代碼吧。
首先咱們定義個類型來實現IMetadataAware接口類型,而根據MVC框架檢索的前提約定,咱們須要把自定義的類型定義爲特性類,如代碼3-1所示:
代碼3-1
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Property,AllowMultiple=false,Inherited=false)] public class MyCustomMetadataAware:Attribute,IMetadataAware { public void OnMetadataCreated(ModelMetadata metadata) { if (metadata != null) { if (metadata.DisplayName == "地址名稱") { metadata.DisplayName = "通過IMetadataAware修改的地址名稱"; } } } }
在代碼3-1中,咱們自定義的類型MyCustomMetadataAware實現了IMetadataAware接口類型,而且在OnMetadataCreated()方法中對metadata參數(Model元數據)進行修改,修改的屬性DisplayName是Model元數據控制器對應屬性顯示的名稱,在這個MyCustomMetadataAware類型中咱們把這個DisplayName屬性值若是符合某種條件下修改掉(爲了配合上面的示例)。
咱們再來看一下咱們的Model定義,如代碼3-2:
代碼3-2
public class Customer { [HiddenInput(DisplayValue=false)] public string CustomerID { get; set; } [Display(Name="姓名")] [UIHint("Password")] public string Name { get; set; } [DataType(DataType.Date)] [Display(Name="註冊日期")] public DateTime RegistrationDate{ get; set; } [UIHint("Address")] public Address Address { get; set; } } public class Address { [Display(Name="地址名稱")] [MyCustomMetadataAware] public string AddressName { get; set; } }
在代碼3-2中,咱們把Model中的Address屬性所對應的Address類型中的AddressName屬性加上了咱們自定義的特性類,意在修改這個屬性最後在頁面上顯示出來的值。
咱們看一下修改後的結果圖8.
圖8
從圖8中咱們能夠清楚的看到對應地址欄的標籤名稱已經被修改掉了,對於系統提供的這個IMetadataAware接口咱們能夠作更多的自定義操做,這種方式的編程模式咱們也是很常見的。
Model元數據部分到這裏就所有結束了,其中也會有不少細節的部分沒有講的很到位、沒有很全面,由於博主是小白有什麼寫的很差的地方朋友們能夠提出來,我會學習而且再來回的修改篇幅,能在這裏爲你們盡一點薄力感到很榮幸,也謝謝你們的支持。下一個系列將是Model綁定的部分,你們敬請期待。