前面的篇幅講解了Model元數(shù)據(jù)生成的過程,并沒有對(duì)Model元數(shù)據(jù)生成過程的內(nèi)部和Model元數(shù)據(jù)結(jié)構(gòu)的詳細(xì)解釋。看完本篇后將會(huì)對(duì)Model元數(shù)據(jù)有更清楚的了解,當(dāng)然了也不會(huì)是特別全面的,因?yàn)楹竺孢€有篇幅。希望能給大家?guī)砗玫男Ч?/p>
創(chuàng)新互聯(lián)建站是一家網(wǎng)站設(shè)計(jì)公司,集創(chuàng)意、互聯(lián)網(wǎng)應(yīng)用、軟件技術(shù)為一體的創(chuàng)意網(wǎng)站建設(shè)服務(wù)商,主營(yíng)產(chǎn)品:響應(yīng)式網(wǎng)站、品牌網(wǎng)站制作、成都全網(wǎng)營(yíng)銷。我們專注企業(yè)品牌在網(wǎng)站中的整體樹立,網(wǎng)絡(luò)互動(dòng)的體驗(yàn),以及在手機(jī)等移動(dòng)端的優(yōu)質(zhì)呈現(xiàn)。成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、移動(dòng)互聯(lián)產(chǎn)品、網(wǎng)絡(luò)運(yùn)營(yíng)、VI設(shè)計(jì)、云產(chǎn)品.運(yùn)維為核心業(yè)務(wù)。為用戶提供一站式解決方案,我們深知市場(chǎng)的競(jìng)爭(zhēng)激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞析悅目的作品,網(wǎng)站的價(jià)值服務(wù)。
什么是Model元數(shù)據(jù)?
生成Model元數(shù)據(jù)的過程【一】
生成Model元數(shù)據(jù)的過程【二】
ModelMetaData的定義、詳解
Model元數(shù)據(jù)應(yīng)用(常用特性應(yīng)用)-1
Model元數(shù)據(jù)應(yīng)用(自定義視圖模板)-2
Model元數(shù)據(jù)應(yīng)用(IMetadataAware接口使用)-3
對(duì)于Model元數(shù)據(jù)的生成可否我們自己來定義呢?回答是肯定的,必須可以阿。MVC框架給我們提供了頂層基類,在調(diào)用的時(shí)候是從當(dāng)前上下文中獲取到系統(tǒng)默認(rèn)實(shí)現(xiàn)類(或者是我們自定義的實(shí)現(xiàn)類)。我們來看一下示例代碼1-1.
代碼1-1
public class MyCustomModelMetadataProvider:DataAnnotationsModelMetadataProvider { protected override ModelMetadata CreateMetadata(IEnumerableattributes, Type containerType, Func
代碼1-1中的MyCustomModelMetadataProvider類型繼承自DataAnnotationsModelMetadataProvider類型,并且重寫了CreateMetadata()的方法,在CreateMetadata()方法中會(huì)根據(jù)參數(shù)attributes中的特性信息來對(duì)Model元數(shù)據(jù)各種屬性來操作賦值。這個(gè)會(huì)在下面說到,代碼1-1中并沒有對(duì)attributes參數(shù)這些來進(jìn)行解析,而只是實(shí)例化了一個(gè)Model元數(shù)據(jù)類型(DataAnnotationsModelMetadata繼承自ModelMetadata)用來返回。這樣定義好了過后系統(tǒng)并不會(huì)調(diào)用我們自定義的實(shí)現(xiàn),而是需要在項(xiàng)目啟動(dòng)的時(shí)候就添加到系統(tǒng)上下文中,我們就在Global.asax文件中的MvcApplication類型里的Application_Start()方法中來添加示例代碼1-2.
代碼1-2
ModelMetadataProviders.Current = new MyCustomModelMetadataProvider();
這樣定義過后,系統(tǒng)框架在執(zhí)行的時(shí)候就會(huì)調(diào)用我們的自定義實(shí)現(xiàn)了,還可以使用前面篇幅的示例來直接運(yùn)行,什么結(jié)果我沒試過不過肯定是不會(huì)有什么特殊效果,真正的目的不在這,而是在CreateMetadata()方法的入口處設(shè)上斷點(diǎn)(圖1)然后我們?cè)俅伟碏5執(zhí)行程序,程序又會(huì)執(zhí)行到我們自定義實(shí)現(xiàn)的CreateMetadata()方法。
圖1
按照上面做的意義何在呢?這樣做的意義在于在每次斷點(diǎn)進(jìn)來的時(shí)候,我們可以打開調(diào)試的即時(shí)窗口,并且輸入CreateMetadata()方法參數(shù)的modelType來查看當(dāng)前所要生成的Model元數(shù)據(jù)對(duì)應(yīng)的類型或者是屬性,也便于我們自己去更深入的學(xué)習(xí)。還有一個(gè)意思就是證明了我上篇所說的那樣生成的過程。
下面我們來看一下系統(tǒng)默認(rèn)提供的DataAnnotationsModelMetadataProvider類型中是怎么對(duì)Model元數(shù)據(jù)進(jìn)行操作的,先看一下默認(rèn)的實(shí)現(xiàn)代碼,
代碼1-3
protected override ModelMetadata CreateMetadata(IEnumerableattributes, Type containerType, Func
在代碼1-3中,我們看到首先會(huì)根據(jù)參數(shù)attributes轉(zhuǎn)換為Attribute集合類型的attributeList變量,然后就是在此集合中搜尋第一個(gè)DisplayColumnAttribute類型的特性,暫且先不說這個(gè)特性類型是干什么的,因?yàn)槲椰F(xiàn)在也不太明白。
然后就是根據(jù)CreateMetadata()方法中的參數(shù)實(shí)例化一個(gè)DataAnnotationsModelMetadata類型的元數(shù)據(jù),這個(gè)類型上面說過了。繼續(xù)往下看,然后就到了從attributeList變量獲取第一個(gè)HiddenInputAttribute類型的特性實(shí)例,在判斷不為空后,對(duì)Model元數(shù)據(jù)DataAnnotationsModelMetadata類型變量result的兩個(gè)屬性開始賦值(下文中對(duì)Model元數(shù)據(jù)DataAnnotationsModelMetadata類型變量result統(tǒng)稱叫result),首先第一個(gè)是Model元數(shù)據(jù)的TemplateHint屬性,這個(gè)屬性表示著這個(gè)Model元數(shù)據(jù)所表示的對(duì)象要使用哪個(gè)視圖模板來生成Html代碼(視圖模板的內(nèi)容這個(gè)系列的后面篇幅會(huì)有講解,到時(shí)候再回頭來看一下,學(xué)習(xí)嘛感覺就是一個(gè)迭代的過程)。然后是HideSurroundingHtml屬性的賦值,對(duì)應(yīng)的是HiddenInputAttribute類型的DisplayValue值,HiddenInputAttribute類型表示的是是否將屬性或者字段值顯示為隱藏的Input元素,如果我們這樣寫的話[HiddenInput(DisplayValue = false)],HideSurroundingHtml屬性值則為true,代表的意思就是使用關(guān)聯(lián)的Html元素來呈現(xiàn)對(duì)象模型,意思就是用HiddenInputAttribute類型所關(guān)聯(lián)隱藏輸入域來呈現(xiàn)我們所指定的屬性或者字段。這里可能有點(diǎn)繞,不過不妨礙,下個(gè)篇幅會(huì)講示例用的效果。
切回主題繼續(xù)講,下面則是從attributeList中獲取UIHintAttribute類型的集合,并且經(jīng)過一番判斷獲取一個(gè)UIHintAttribute類型的實(shí)例,并且還是賦值到TemplateHint屬性(上面說過),這里就覆蓋掉了,在我們使用默認(rèn)的Model元數(shù)據(jù)提供程序的時(shí)候就要注意這些了,再繼續(xù)往下看。
從attributeList中獲取第一個(gè)EditableAttribute類型的實(shí)例,并且根據(jù)EditableAttribute類型實(shí)例中的AllowEdit屬性值來設(shè)置result的IsReadOnly屬性值,代表著指示這個(gè)模型是否只讀,EditableAttribute類型指示模型是否可編輯的意思和下面的ReadOnlyAttribute類型很像,只不過同樣是實(shí)現(xiàn)只讀效果兩個(gè)類型使用中設(shè)置的屬性值是相反的。
同樣是從attributeList獲取符合類型條件的第一個(gè)DataTypeAttribute類型實(shí)例,還有個(gè)是DisplayFormatAttribute類型實(shí)例,這里會(huì)調(diào)用默認(rèn)的提供程序里的另一個(gè)函數(shù),在此就不做多的介紹了,我就稍微的說一下就行了。為什么把這兩個(gè)放一起呢?因?yàn)樗麄兌际菍?duì)指定的模型輸出格式的設(shè)置有關(guān)。
ScaffoldColumnAttribute類型實(shí)例表示著是否使用基架(模板視圖輔助器的一種,EditorForModel屬于其中之一),當(dāng)某項(xiàng)屬性上使用了這個(gè)特性類的時(shí)候,在使用基架的時(shí)候會(huì)直接跳過這項(xiàng)屬性,在生成的頁面中也不會(huì)發(fā)現(xiàn)這項(xiàng)屬性。(遭到了嫌棄)
同樣的DisplayAttribute類型的實(shí)例也是從attributeList獲取符合類型條件的第一個(gè),DisplayAttribute類型實(shí)例里有個(gè)Name屬性會(huì)被設(shè)置到result的DisplayName屬性,這個(gè)屬性的意思就是指定的模型顯示到頁面的值。而DisplayNameAttribute類型實(shí)例的意思和DisplayAttribute類型的相近,只不過DisplayNameAttribute類型可以用于類類型,轉(zhuǎn)定義我們一看便知。
最后對(duì)于RequiredAttribute類型實(shí)例的意思會(huì)在Model驗(yàn)證篇幅中說明。