問題1:什麼叫Model元數據?html
Model元數據,是針對數據類型的一種描述信息。因爲複雜類型(或者說類型嵌套的存在,好比CustomerModel中有一個屬性爲複雜類型Address)的存在,所以Model 元數據爲樹形結構:數據庫
1 //namespace:System.Web.Mvc 2 public class ModelMetadata 3 { 4 //其它成員 5 6 //當前模型類型 7 //假若用數據庫中樹形結構解釋,這個屬性至關於Id 8 public Type ModelType { get; set; } 9 10 //當前模型類型所屬類型 11 //假若用數據庫中樹形結構解釋,這個屬性至關於ParentId 12 public Type CotainerType { get; set; } 13 14 }
在ASP.NET MVC中對應被定義爲類型 「ModelMetadata」,其做用主要體如今如下兩個方面:框架
一、控制數據類型自己及其成員屬性在界面上的呈現方式;測試
1 //namespace:System.Web.Mvc 2 public class ModelMetadata 3 { 4 //其它成員 5 6 //模型名稱 7 public virtual string DisplayName { get; set; } 8 }
上面代碼將MVC框架定義的Model元數據精簡爲一個屬性,該屬性用於呈現Model或者Model數據中元素在UI上的顯示名稱。這樣說過於抽象,下面的的代碼是咱們在MVC程序開發時候常寫寫的界面模型類:ui
1 //用戶界面模型 2 public class CustomerModel 3 { 4 [DisplayName("用戶姓名")] 5 public string Name{get;set;} 6 7 public string Gender{get;set;} 8 }
給CustomerModel的 Namei屬性添加DisplayName 特性,Gender屬性不作任何操做,假若在強類型視圖上使用@Html.DisplayFor(d=>d.Name); @Html.DisplayFor(d=>d.Gender)顯示用戶信息,會發現Name會顯示「用戶姓名」,而Gender屬性的顯示僅僅是原樣輸出爲Gender;spa
事實上,DisplayName特性就是經過改變ModelMetadata的DisplayName來達到這一效果,也就是說,特性的做用在於定製ModelMetadata。code
二、Model綁定和驗證提供必不可少的元數據orm
綁定之後說起,至於驗證,看下面代碼:htm
1 //namespace:System.Web.Mvc 2 public class ModelMetadata 3 { 4 //其它成員 5 6 //是否必填 7 public virtual bool IsRequired{ get; set; } 8 }
1 1 //用戶界面模型 2 2 public class CustomerModel 3 3 { 4 4 [Required] 5 5 public string Name{get;set;} 6 6 7 7 public string Gender{get;set;} 8 8 }
同理,Required特性定製了Model元數據中的IsRequired屬性以達到針對模型的驗證。對象
問題2:如何針對Model元數據進行定製?
問題1中說明了ModelMetadata類的各屬性控制了數據在UI中的呈現、驗證、綁定。那麼如何獲取或設置ModelMetadata類的各屬性呢?答案是使用特性【Attribute】。
能夠用於定製Model元數據的特性有如何:
一、UIHintAttribute
HtmlHelper定義了一系列模板方法,好比DisplayFor/Display、EditorFor/Editor,所謂模板方法,就是Model數據與HTML標籤的封裝。其效果相似於強類型的PartialView。
UIHintAttribute特性的做用就在於爲Model中的屬性或者字段顯示指定模板,當UI出現@Html.DisplayFor(d=>d.Name)語句,ASP.NET MVC將會用UIHintAttribute指定的模板展現Model數據。
MVC有一套尋找模板的規則,默認嗎沒有指定模板狀況下,MVC將從@DisplayFor(d=>d.Name) lamba表達式中獲得Name的數據類型,根據該數據類型在預約義的目錄下去尋找不一樣的模板。而同一種數據類型模板,又能夠分爲編輯模板(EditorFor)、顯示模板(DisplayFor)。假若指定了一個具體的模板名稱,ASP.NET MVC 會自動採用該模板來生成最終的HTML。而指定的模板一般按顯示模式定義在EditorTemplates目錄或DisplayTemplates目錄下。這些目錄能夠存在於Views/Shared、Views/{ControllerName}下;
能夠作個測試。
首先定義數據模型:
1 public class CustomerModel 2 { 3 [UIHint("Name")] 4 public string Name { get; set; } 5 6 public string Gender { get; set; } 7 }
經過UIHint特性指定了顯示模板爲「Name」;
控制器中實例一個CustomerModel對象,並傳遞給視圖View。
1 public ActionResult Index() 2 { 3 CustomerModel model = new CustomerModel() 4 { 5 Name = "小李", 6 Gender = "男" 7 }; 8 return View(model); 9 }
新建View以下:
1 <body> 2 <div> 3 @Html.DisplayFor(d=>d.Name)<br /> 4 @Html.DisplayFor(d => d.Gender) 5 </div> 6 </body> 7 </html>
主要Gender屬性咱們並無指定顯示模板,接着須要在DisplayTemplates目錄下新建Name 視圖:
@model string <h3 style="color:red;">我是自定義模板:@Html.TextBox(Model,Model)</h3>
最終運行結果以下:
APS.NET MVC預約義模板總共有這麼幾個:
模板名稱 | 模板做用 | 模板說明 |
EmailAddress | Emal地址呈現 | 僅具備顯示模式 |
HiddenInput | 顯示模式下文本顯示; 編輯模式下文本+一個隱藏的<inptu> |
HiddenInput(DisplayValue=false) 時,顯示模式、編輯模式顯示文本均消失。 |
Html | 將模型數據中包含的HTML原樣呈現 | 僅限於顯示模式,效果與Html.Raw()相同 |
Text與String | ---- | 顯示模式下直接以文本的形式輸出,編輯模式下對應一個單行文本框 |
MultilineText | 多行文本(<input type="text"/>) | 僅限於編輯模式 |
Password | 密碼框 | 僅限於編輯模式 |
Decimal | 小數位統一化爲兩位小數 | 顯示模式:文本;標記哦是:單行文本框 |
Boolean | ---- | 顯示模式:一個checkbox,disabled=true;編輯模式:一個chekbox,加一個隱藏的checkbox,二者name相同,value相異 |
Colloection | 集合數據呈現 | …………………… |
Object | 備胎 | 找不到其它,最終就是它。根據元數據DisplayName生成一個<div> |
2.HiddenInputAttribute與ScaffoldColumnAttribute
經過應用HiddenInputAttribute,該特性的目標對象以只讀的形式顯示出來,若是不但願顯示,能夠設置特性的DisplayValue爲false([HiddenInput(DisplayValue=false)])。
經過應用ScaffoldColumnAttribute,該特性的目標對象不會出如今最終生成的Html中,區別與HiddenInputAttribute,HiddenInputAttribute目標元素會以type=hidden的形式出如今最終生成的Html當中;
3.DataTypeAttribute與DisplayFormatAttribute
這裏的DataTypeAttribute不一樣於CLR類型,而是經過系統定義的枚舉類型:DataType來表示具備某種顯示格式的數據類型。枚舉DataType定義以下:
1 // 摘要: 2 // 表示與數據字段和參數關聯的數據類型的枚舉。 3 public enum DataType 4 { 5 // 摘要: 6 // 表示自定義的數據類型。 7 Custom = 0, 8 // 9 // 摘要: 10 // 表示時間上的一刻,以日期和當天的時間表示。 11 DateTime = 1, 12 // 13 // 摘要: 14 // 表示日期值。 15 Date = 2, 16 // 17 // 摘要: 18 // 表示時間值。 19 Time = 3, 20 // 21 // 摘要: 22 // 表示對象存在的一段連續時間。 23 Duration = 4, 24 // 25 // 摘要: 26 // 表示電話號碼值。 27 PhoneNumber = 5, 28 // 29 // 摘要: 30 // 表示貨幣值。 31 Currency = 6, 32 // 33 // 摘要: 34 // 表示所顯示的文本。 35 Text = 7, 36 // 37 // 摘要: 38 // 表示一個 HTML 文件。 39 Html = 8, 40 // 41 // 摘要: 42 // 表示多行文本。 43 MultilineText = 9, 44 // 45 // 摘要: 46 // 表示電子郵件地址。 47 EmailAddress = 10, 48 // 49 // 摘要: 50 // 表示密碼值。 51 Password = 11, 52 // 53 // 摘要: 54 // 表示 URL 值。 55 Url = 12, 56 // 57 // 摘要: 58 // 表示圖像的 URL。 59 ImageUrl = 13, 60 }
事實上,DataTypeAttribute是一個驗證特性,MVC在數據綁按期間將會根據應用了DataTypeAttribute的目標元素驗證。
DisplayFormatAttribure用於控制目標元素的顯示形式。
4 其它
EditableAttribute與ReadOnlyAttributr控制目標元素的可讀寫性,二者實質等同,同時出現的狀況下,前者具備更高的優先級;
DisplayAttribute與DisplayNameAttribute 爲目標元素定義一些說明性文字。同時出現的狀況下,前者具備更高的優先級;此外,因爲DisplayAttribute設置的文字都是面向最終用戶的,因此有必要對其斤西瓜本地化,因此該特性提供了ResourceType屬性用於表明採用的資源文件類型。
RequiredAttribute顧名思義,其將目標元素設置爲必需的數據成員。