ASP.NET MVC Model中繼資料(二)

來源:互聯網
上載者:User

標籤:asp.net mvc metadata   asp.net mvc   .net   c#   mvc   

ASP.NET MVC Model中繼資料(二)前言

在上篇中,給大家留個對Model中繼資料的印象,並沒有對Model中繼資料有過多的講解,而在本篇中也不會對Model中繼資料的本身來解釋,而是針對於它的產生過程,讓大家能夠清楚的瞭解到系統架構是在什麼時候產生Model中繼資料的,對於Model中繼資料產生篇幅初定為兩篇,本篇為它的整體的產生過程,下篇則為詳細的產生過程並且會對它本身做一個粗略的介紹,希望大家看完能夠有所收穫

 

Model中繼資料
  • 什麼是Model中繼資料?
  • 產生Model中繼資料的過程【一】
  • 產生Model中繼資料的過程【二】
  • ModelMetaData的定義、詳解
  • Model中繼資料應用(常用特性應用)-1
  • Model中繼資料應用(自訂視圖模板)-2
  • Model中繼資料應用(IMetadataAware介面使用)-3

 

產生Model中繼資料的過程【一】

還是如前篇說的那樣,既然叫Model中繼資料(Model指的是視圖模型)那麼肯定跟Model有關係了,而在我們MVC項目中一般是什麼時候會對Model進行操作呢?一般情況下都是在通過控制器的行為請求一個視圖的時候,而控制器行為的參數即為Model,然後在行為方法中做一些處理然後再傳遞給視圖。然後再根據上篇最後的一個來看,

圖1

 

產生Model中繼資料的地方已經鎖定到了行為方法,想象一下肯定是不可能在行為方法中來產生的,因為那是我們自訂邏輯的地方。那是在什麼地方呢?

想必大家看過之前的對過濾器篇幅的介紹,在ASP.NET MVC 過濾器(三)中對行為過濾器的執行過程講解的時候,中間有提到過模型繫結器,並且說到了系統架構所要使用到的自訂模型繫結器,而使用這個自訂模型繫結器所需要的兩個參數是非常重要的,一個是表示當前控制器內容相關的對象ControllerContext,另一個則是產生Model中繼資料的關鍵,也是調用自訂模型繫結器的關鍵參數ModelBindingContext類型。看下

圖2

 

而在ModelBindingContext類型中有個重要的屬性,即為Model中繼資料類型ModelMetadata,由此可以知道在我們的控制器行為執行之前,對應控制器行為的Model的Model中繼資料ModelMetadata類型已經產生了。(這部分內容詳見過濾器篇幅)

而它是怎麼產生的呢?是通過系統架構中預設提供的提供者來產生的,是哪些個類型呢?

圖3

那我們就先看一下最頂層的基類ModelMetadataProvider的定義:

代碼1-1

public abstract class ModelMetadataProvider    {        // 摘要:        //     在衍生類別中重寫時,初始化派生自 System.Web.Mvc.ModelMetadataProvider 類的對象的新執行個體。        protected ModelMetadataProvider();        public abstract IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);        public abstract ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);        public abstract ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);    }

 

非常明白的定義,三個抽象方法,這裡我們只需先看GetMetadataForType()方法,其它兩個暫時不管下篇中會有講到,因為先看GetMetadataForType()方法呢?因為它是產生ModelMetadata類型的入口,第一個參數暫時忽略,第二個參數嘛很重要了,是ParameterDescriptor類型的ParameterType屬性,表示著Model的類型(也就是控制器方法參數的Type類型),現在我們來看4

圖4

 

圖4中藍色線條為主要流程,紅色線條是在藍色處理之後執行的流程。

上面說到,入口方法是為抽象方法,那是怎麼具體實現的呢,從圖4中可以看到是由實現了ModelMetadataProvider的類型AssociatedMetadataProvider類型來進行處理的,從圖4可以看到首先是擷取一個AttributeList的類型,AttributeList類型表示著從AssociatedMetadataProvider類型GetMetadataForType()方法參數modelType類型上的特性集合,對了AssociatedMetadataProvider類型是比較重要的類型,我們先來看一下它的定義:

public abstract class AssociatedMetadataProvider : ModelMetadataProvider    {        protected AssociatedMetadataProvider();        protected abstract ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName);        protected virtual IEnumerable<Attribute> FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable<Attribute> attributes);        public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType);        protected virtual ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor);        public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName);        public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType);        protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type);    }

方法有點多,暫時不用管,大多數方法都是用來在遞迴產生Model中繼資料的時候使用的(具體的過程會在下篇中講解)。好了切回主題接著上面的內容來說,AttributeList類型的由來,是通過ModelMetadataProvider的GetTypeDescriptor()方法根據Model的類型(這裡暫且先這麼理解,等看完下個篇幅就會知道這裡也有可能是Model中的屬性類型)來產生一個ICustomTypeDescriptor類型(可以想象成這是對於一種物件類型中繼資料描述對象的抽象定義。讀起來有點繞口,但是確實是這麼個意思)。而系統會有個預設的自訂實現來實現這個介面類型,我們通過這個預設的實現來獲得Model類型的AttributeList類型。

在有了AttributeList類型後,我們就可以調用AssociatedMetadataProvider類型的CreateMetadata()方法來建立Model中繼資料對象,但是這個CreateMetadata()的定義是抽象的,而真正的實現是由繼承了AssociatedMetadataProvider類型的DataAnnotationsModelMetadataProvider類型,由此過後我們產生得到ModelMetadata中繼資料對象(真正的過程比較繁瑣,不然也不會另起一篇專門用來講解產生的過程),得到了Model中繼資料對象過後並沒有結束,而是繼續調用了AssociatedMetadataProvider類型的ApplyMetadataAwareAttributes()方法,並在此方法中,系統架構會調用我們自訂實現了IMetadataAware介面類型的對象,來對Model中繼資料對象進行個人化修改,並且最後才會真正的返回Model中繼資料對象。

有可能看到這裡有的朋友對Model中繼資料還是不怎麼清楚和瞭解,朋友們急我也急,如果我分享的這些知識大家看完都不知所云那我又是何必呢。先不要急看了多少就是多少在看完這個Model中繼資料系列的文章後應該會有所瞭解,將在後續的篇章中慢慢的揭開它的秘密。謝謝大家的支援。

 

 

 

 

金源

出處:http://blog.csdn.net/jinyuan0829

本文著作權歸作者和CSDN共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.