程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET MVC Model元數據及其定制: Model元數據的定制

ASP.NET MVC Model元數據及其定制: Model元數據的定制

編輯:關於ASP.NET

在《上篇》我們已經提到過了,Model元數據的定制是通過在作為Model的數據類型極其屬性成員上應用相應的特性來實現,這些用於聲明式元數據定義的特性大都定義在System.ComponentModel.DataAnnotations.dll程序集中,程序集的名稱同時也是對應的命名空間名稱,所以我們可以它們為數據注解特性(Data Annotation Attribute),接下來我們來介紹一些常用的數據注解特性,以及它們對於元數據具有怎樣的影響。

一、UIHintAttribute

HtmlHelper和HtmlHelper<TModel>定義了一系列的基於Model的模板方法,比如Display/DisplayFor、Editor/EditorFor、DisplayForModel/EditForModel、Lable/LabelFor和DisplayText/DisplayTextFor。所謂模板方法,就是說我們在通過調用這些方法將代表Model的數據呈現在View中的時候,並不對最終呈現的UI元素進行顯失地控制,而采用默認或者指定的模板來決定最終呈現在浏覽器中的HTML。每個具體的模板均具有相應的名稱,這些模板方法在進行Model呈現的時候根據對應的Model元數據得到對應的模板名稱。具體來說,模板的名稱通過ModelMetadata的TemplateHint屬性表示,如下面的代碼片斷所示,這是一個字符串類型的可讀寫屬性。

   1: public class ModelMetadata
2: {
3: //其他成員
4: public virtual string TemplateHint{get;set;}
5: }

ModelMetadata的TemplateHint屬性可以通過UIHintAttribute特性來定制。如下面的代碼片斷所示,UIHintAttribute具有PresentationLayer和UIHint兩個只讀屬性,分別用於限制展現層的類型(比如“HTML”、“Silverlight”、“WPF”、“WinForms”等和模板名稱,這兩個屬性均在構造函數中初始化。

   1: [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple=true)]
2: public class UIHintAttribute : Attribute
3: {
4: //其他成員
5: public UIHintAttribute(string uiHint);
6: public UIHintAttribute(string uiHint, string presentationLayer);
7:
8: public string PresentationLayer { get; }
9: public string UIHint { get; }
10: }

通過應用在UIHintAttribute上的AttributeUsageAttribute定義我們不難看出,由於其AllowMultiple屬性被設置為True,意味著我們可以在相同的目標元素上應用多個UIHintAttribute特性,那麼哪一個會被選擇用於定制Model元數據呢?

如果多個UIHintAttribute應用到了相應的元素(類型或者屬性),會先選擇一個PresentationLayer屬性為“MVC”(不區分大小寫)的UIHintAttribute。如果這樣的UIHintAttribute不存在,則選擇一個PresentationLayer屬性值為空的UIHintAttribute。值得一提的是,如果具有多個匹配的UIHintAttribute可控選擇,系統會選擇第一個,但是通過反射獲取到的Attribute的順序和Attribute被標注的屬性沒有直接的關系。

接下來我們通過一個簡單的實例來演示UIHintAttribute特性對Model元數據的影響,以及對應用在相同目標元素上的多個UIHintAttribute的選擇策略。考慮到重用性,我們編寫了如下一個靜態輔助方法GetModelMetadata<TModel>用於獲取Model類型為TModel針對指定屬性的Model元數據。

   1: public static ModelMetadata GetModelMetadata<TModel>(string propertyName)
2: {
3: ModelMetadataProvider provider = ModelMetadataProviders.Current;
4: ModelMetadata containerMetadata = new ModelMetadata(provider, null, () => null, typeof(TModel), null);
5: return containerMetadata.Properties.FirstOrDefault(m => m.PropertyName == propertyName);
6: }

我們通過如下的代碼定義了一個類型為Model的數據類型,三個屬性Foo、Bar和Baz定義其中。對於屬性Bar來說,我們同時應用了兩個模板名稱分別為“Template A”和“Template B”的UIHintAttribute特性,後者將字符“Mvc”作為presentationLayer參數的值。屬性Baz通用應用了基於模板名稱“Template A”的UIHintAttribute特性。

   1: public class Model
2: {
3: public string Foo { get; set; }
4:
5: [UIHint("Template A")]
6: [UIHint("Template B", "Mvc")]
7: public string Bar { get; set; }
8:
9: [UIHint("Template A")]
10: public string Baz { get; set; }
11: }

現在我們在一個控制台程序中編寫如下的測試程序。我們通過上面定義的輔助方法GetModelMetadata<TModel>創建針對定義在數據類型Model中的Foo、Bar和Baz三個屬性的ModelMetadata,並分別打印出對應的TemplateHint屬性。

   1: ModelMetadata foo = GetModelMetadata<Model>("Foo");
2: ModelMetadata bar = GetModelMetadata<Model>("Bar");
3: ModelMetadata baz = GetModelMetadata<Model>("Baz");
4:
5: Console.WriteLine("Foo: {0}", foo.TemplateHint??"N/A");
6: Console.WriteLine("Bar: {0}", bar.TemplateHint ?? "N/A");
7: Console.WriteLine("Baz: {0}", baz.TemplateHint ?? "N/A");

上面的測試程序執行之後會在控制台上產生如下的輸出結果,這和我們上面介紹的關於UIHintAttribute特性針對Model元數據的定制,以及針對應用在相同目標元素上的多個UIHintAttribute特性的選擇策略是相符的。

   1: Foo: N/A
2: Bar: Template B
3: Baz: Template A

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved