<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

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

      Contronoller激活之后,ASP.NET MVC會根據當前請求上下文得到目標Action的名稱,然后解析出對應的方法并執行之。在整個Action方法的執行過程中,Model元數據的解析是一個非常重要的環節。ASP.NET MVC中的Model實際上View Model,表示最終綁定到View上的數據,而Model元數據描述了Model的數據結構,以及Model的每個數據成員的一些特性。正是有了Model元數據的存在,才使模板化HTML的呈現機制成為可能。此外,Model元數據支撐了ASP.NET MVC的Model驗證體系,因為針對Model的驗證規則正是定義在Model元數據中。ASP.NET MVC的Model元數據通過類型ModelMetadata表示。ModelMetadata通過一系列的屬性描述了Model及其成員相關的元數據信息,在正式介紹這些元數據選項之前,我們很有必要先來了解一下Model元數據層次化結構。[本文已經同步到《How ASP.NET MVC Works?》中]

      目錄
      一、Model元數據層次化結構
      二、基本Model元數據信息
      三、Model元數據的定制
          UIHintAttribute
          HiddenInputAttribute與ScaffoldColumnAttribute
          DataTypeAttribute與DisplayFormatAttribute
          EditableAttribute與ReadOnlyAttribute
          DisplayAttribute與DisplayNameAttribute
          RequiredAttribute
      四、IMetadataAware接口
          AllowHtmlAttribute
          實例演示:創建實現IMetadataAware接口的特性定制Model元數據

      一、Model元數據層次化結構

      作為Model的數據類型可以一個和簡單的字符串或者是一個值類型的對象,也可能是一個復雜的數據類型。對于一個復雜的數據類型,基于類型本身和數據成員的元數據都通過一個ModelMetadata來表示,而某個數據成員又可能是一個復雜類型,所以通過ModelMetadata對象表示的Model元數據實際上具有一個樹形層次化結構。

      舉個例子,我們具有一個具有如下定義的表示聯系人的數據類型Contact。屬性Name、PhoneNo、EmailAddress和Address分別代表姓名、電話號碼、郵箱地址和聯系地址。聯系地址通過另一個數據類型Address表示,屬性Province、City、District和Street分別表示所在省份、城市、城區和街道。

         1: public class Contact
         2: {
         3:     public string Name { get; set; }
         4:     public string PhoneNo { get; set; }
         5:     public string EmailAddress { get; set; }
         6:     public Address Address { get; set; }
         7: }
         8: public class Address
         9: {
        10:     public string Province { get; set; }
        11:     public string City { get; set; }
        12:     public string District { get; set; }
        13:     public string Street { get; set; }
        14: }

      如果將Contact類型作為Model,作為其元數據的ModelMetadata不僅僅具有Contact類型本身和其屬性成員的描述,由于其Address屬性是一個復雜類型,元數據還需要描述定義在該類型中的4個屬性成員。下圖反映基于Contact類型的Model元數據的層次化結構。

      image

      表示Model元數據的ModelMetadata類型不僅用于描述某個作為Model的數據類型,還用于遞歸地描述其所有屬性成員(不包含字段成員),所以ModelMetadata具有一個樹型層次化結構,這也可以從ModelMetadata的定義可以看出來。

         1: public class ModelMetadata
         2: {
         3:     //其他成員
         4:     public virtual IEnumerable<ModelMetadata> Properties { get; }
         5: }

      如上面的代碼片斷所示,ModelMetadata具有一個類型為IEnumerable<ModelMetadata>的只讀屬性Properties,表示用于描述屬性/字段成員的ModelMetadata集合。ModelMetadata的層次化結構可以通過如下圖所示的UML來體現。由于基于類型的ModelMetadata和基于數據成員的ModelMetadata是一種包含關系,我們可以將前者稱為后者的容器(Container)。

      image

      二、基本Model元數據信息

      基于作為Model類型創建的元數據主要是為View實現模板化HTML呈現和數據驗證服務的,我們可以通過在類型和數據成員上應用相應的特性控制Model在View中的呈現方式或者定義相應的驗證規則。在介紹聲明式Model元數據編程方式之前,我們先來介紹表示Model元數據的ModelMetadata類型中與UI呈現和數據驗證無關的基本屬性。

         1: public class ModelMetadata
         2: {
         3:    //其他成員
         4:     public Type ModelType { get; }
         5:     public virtual bool IsComplexType { get; }
         6:     public bool IsNullableValueType { get; }
         7:     public Type ContainerType { get; }
         8:  
         9:     public object Model { get; set; }
        10:     public string PropertyName { get; }
        11:  
        12:     public virtual Dictionary<string, object> AdditionalValues { get; }
        13:     protected ModelMetadataProvider Provider { get; set; }
        14: }

      如上面的代碼片斷所示,ModelMetadata具有四個類型相關的只讀屬性。ModelType表示Model本身的類型,比如說針對上面定義的Contact類型的ModelMetadata對象,其ModelType屬性值就是Contact類型;而針對其屬性的ModelMetadata對象,則具體的屬性類型作為它的ModelType屬性。屬性IsComplexType和IsNullableValueType分別表示以ModelType屬性表示的Model類型是一個復雜類型和可空值類型。

      在這里判斷某個類型是否是復雜類型的條件只有一個,即是否允許字符串類型向該類型的轉換。具體來說,將通過ModelType屬性表示的Model類型作為傳輸傳入TypeDescriptor的靜態方法GetConverter得到一個TypeConverter對象,如果TypeConverter不支持從字符串類型的轉換則認為是復雜類型。所以所有的基元類型(Primative Type)均不是復雜類型,所有可空值類型(Nuallable Type)均不是是復雜類型。對于一個默認為復雜類型的自定義的數據類型,我們可以通過TypeConverterAttribute特性標注一個支持從字符串類型轉換的TypeConverter使之轉變成非復雜類型。

      如下面的代碼片斷所示,我們定義了一個表示二維坐標的Point類型,由于我們在該類型上應用了一個TypeConverterAttribute特性指定了類型為PointTypeConverter的TypeConverter。由于PointTypeConverter支持從字符串到Point類型之間的轉換,所以Point并不是一個復雜類型。

         1: [TypeConverter(typeof(PointTypeConverter))]
         2: public class Point
         3: {
         4:     public double X { get; set; }
         5:     public double Y { get; set; }
         6:     public Point(double x, double y)
         7:     {
         8:         this.X = x;
         9:         this.Y = y;
        10:     }
        11:     public static Point Parse(string point)
        12:     { 
        13:         string[] split = point.Split(',');
        14:         if(split.Length != 2)
        15:         {
        16:             throw new FormatException("Invalid point expression.");
        17:         }
        18:         double x;
        19:         double y;
        20:         if (!double.TryParse(split[0], out x) || 
        21:             !double.TryParse(split[1], out y))
        22:         { 
        23:             throw new FormatException("Invalid point expression.");
        24:         }
        25:         return new Point(x, y);
        26:     }
        27: }
        28: public class PointTypeConverter : TypeConverter
        29: {
        30: public override bool CanConvertFrom(ITypeDescriptorContext context, 
        31:    Type sourceType)
        32:     {
        33:         return sourceType == typeof(string);
        34:     }
        35:  
        36: public override object ConvertFrom(ITypeDescriptorContext context, 
        37:     CultureInfo culture, object value)
        38:     {
        39:         if (value is string)
        40:         {
        41:             return Point.Parse(value as string);
        42:         }
        43:         return base.ConvertFrom(context, culture, value);
        44:     }
        45: }

      通過上面的介紹我們知道表示Model元數據的ModelMetadata具有一個樹形的層次結構,某個節點可以看成了其子節點的容器,而ContainerType這是表述容器的類型。同樣以前面定義的Contact類型為例,基于該類型本身的ModelMetadata是整個層次樹的根節點,所以ContainerType返回Null;基于屬性Address的ModelMetadata的ContainerType屬性返回Contact類型;而基于Address的屬性Province的ModelMetadata的ContainerType屬性值則是Address類型。

      ModelMetadata的Model屬性代表的是作為Model的對象。如果將上面定義的Contact對象作為View的Model,那么表示該Model本身元數據的ModelMetadata對象來說,其Model屬性就是該Contact對象;對于基于Contact某個屬性的ModelMetadata對象則將對應的屬性值作為自己的Model。值得一提的是,該屬性是可讀可寫的,意味著我們可以隨時根據需要改變它。另一個屬性PropertyName表示對應的屬性值,對于根節點ModelMetadata來說,該屬性總是返回Null。

      ModelMetadata的AdditionalValues屬性返回一個字典對象,用于存儲一些自定義的屬性,字典元素的Key和Value分別代表自定義屬性的名稱和值。對于自定義屬性的添加,我們可以在數據類型或者其數據成員上應用AdditionalMetadataAttribute特性來實現。如下面的代碼片斷所示,AdditionalMetadataAttribute具有Name和Value兩個只讀屬性分別表示自定義屬性的名稱和值,它們直接通過構造函數進行初始化。AdditionalMetadataAttribute實現了IMetadataAware接口,對于Model元數據的定制來說,這是一個非常重要并且實用的接口,我們將在下篇對其進行單獨介紹。

         1: [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Property | 
         2:     AttributeTargets.Class, AllowMultiple=true)]
         3: public sealed class AdditionalMetadataAttribute : Attribute, IMetadataAware
         4: {
         5:     public AdditionalMetadataAttribute(string name, object value);
         6:     public void OnMetadataCreated(ModelMetadata metadata);
         7:     public string Name { get; }
         8:     public object Value { get;}
         9: }

      ModelMetadata的屬性Provider是一個ModelMetadataProvider對象,顧名思義,ModelMetadataProvider是ModelProvider的提供者。ModelProvider是ASP.NET MVC整個Model元數據系統的核心,我們將在后續的博文中對其進行單獨講述。

      ASP.NET MVC Model元數據及其定制: 初識Model元數據
      ASP.NET MVC Model元數據及其定制: Model元數據的定制
      ASP.NET MVC Model元數據及其定制:一個重要的接口IMetadataAware

      posted @ 2012-04-11 07:32  Artech  閱讀(18357)  評論(27)    收藏  舉報
      主站蜘蛛池模板: 国产国产午夜福利视频| 西西大胆午夜人体视频| 国产999久久高清免费观看| 成人网站国产在线视频内射视频 | 亚洲夜色噜噜av在线观看| 中文字幕亚洲综合久久| 亚洲丰满熟女一区二区蜜桃| 性一交一乱一乱一视频| 大又大又粗又硬又爽少妇毛片 | 少妇被粗大猛进进出出| 视频一区二区不中文字幕| 黑人大荫道bbwbbb高潮潮喷| 亚洲尤码不卡av麻豆| 成人国产精品日本在线观看| 亚洲国产成人av国产自| 国产精品中文一区二区| 国产不卡精品视频男人的天堂| 国内免费视频成人精品| 公主岭市| 国产精品成人久久电影| 久久一日本道色综合久久| 亚洲VA中文字幕无码久久不卡| 精品久久久久久国产| 无码精品一区二区免费AV| 在线精品国精品国产不卡| 达拉特旗| 综合偷自拍亚洲乱中文字幕 | 国产AV无码专区亚洲AV漫画 | 最新中文字幕av无码专区不| 真实国产乱子伦视频| 国产女人在线视频| 成人片黄网站a毛片免费| 在线看片免费人成视频久网| 日本道精品一区二区三区| 精品乱码一区二区三四五区| 日韩av一区二区精品不卡| 日韩欧美在线综合网另类| 亚洲精品区二区三区蜜桃| 美女无遮挡免费视频网站| 欧美福利电影A在线播放| 国产成人永久免费av在线|