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

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

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

      ASP.NET MVC以ValueProvider為核心的值提供系統: NameValueCollectionValueProvider

      在進行Model綁定過程中,需要根據基于Action方法參數的綁定上下文從請求數據中提取相應的數據以提供相應的數據。具體來說,Model綁定的數據具有多個來源,可能來源于Post的表單或者JSON字符串,或者來源于當前的路由數據,也可能來源于請求地址的插敘字符串。ASP.NET MVC將這種基于不同數據來源的數據獲取/提供機制實現在一個叫做ValueProvider的組件中。[本文已經同步到《How ASP.NET MVC Works?》中]

      目錄
      一、IValueProvider與ValueProviderResult
      二、NameValueCollectionValueProvider
      三、兩種前綴形式
      四、實例演示:返回指定前綴的Key
      五、FormValueProvider與QueryStringValueProvider

      一、IValueProvider與ValueProviderResult

      一般來講,一個ValueProvider采用的數據源是一個字典類型的數據結構,我們通過它從這個字典中獲取一個Key與當前綁定上下文匹配的值。ValueProvider實現了具有如下定義的接口IValueProvider,GetValue方法根據指定的Key從數據源中獲取對應的值對象,這個Key是基于當前綁定上下文的。這個Key和存在于數據源中對應數據條目的Key可能并非完全一致,后者可能在前者基礎上添加相應的前綴,而ContainsPrefix方法用于判斷數據源字典的Key是否具有指定的前綴。

         1: public interface IValueProvider
         2: {
         3:     bool ContainsPrefix(string prefix);
         4:     ValueProviderResult GetValue(string key);
         5: }

      IValueProvider的GetValue返回的是一個ValueProviderResult對象,我們可以將ValueProviderResult看成是對ValueProvider提供對象的封裝。如下面的代碼片斷所示,ValueProviderResult具有三個只讀屬性,其中RawValue表示原始的值對象。而AttemptedValue表示以值對象的字符串表示,該屬性主要用于顯示。

         1: [Serializable]
         2: public class ValueProviderResult
         3: {    
         4:     public ValueProviderResult(object rawValue, string attemptedValue, CultureInfo culture);    
         5:     public object ConvertTo(Type type);
         6:     public virtual object ConvertTo(Type type, CultureInfo culture);
         7:  
         8:     public string AttemptedValue { get; }
         9:     public CultureInfo Culture { get; }
        10:     public object RawValue { get; }
        11: }

      ValueProviderResult提供了兩個ConvertTo方法重載以實現向指定目標類型的轉換。某些類型的格式化行為依賴于相應的語言文化(比如時間、日期和貨幣等),而這個輔助格式湖的語言文化信息通過Culture屬性表示。其中第一個ValueProviderResult方法重載通過屬性Culture表示的語言文化進行類型轉化。

      二、NameValueCollectionValueProvider

      前面已經說過,Model數據源一般具有類似于字典的結構,而NameValueCollection可以表示為Key不具有唯一性的字典,將NameValueCollection對象作為數據源的ValueProvider通過具有如下定義的NameValueCollectionValueProvider類型表示。表示數據源的NameValueCollection對象在構造函數中指定,構造函數的另一個CultureInfo類型的參數表示服務于數據轉換的語言文化信息。

         1: public class NameValueCollectionValueProvider : IUnvalidatedValueProvider, IEnumerableValueProvider, IValueProvider
         2: {   
         3:     //其他成員
         4:     public NameValueCollectionValueProvider(NameValueCollection collection,  CultureInfo culture);
         5:  
         6:     public virtual bool ContainsPrefix(string prefix);
         7:     public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix);
         8:     public virtual ValueProviderResult GetValue(string key);
         9:     public virtual ValueProviderResult GetValue(string key, bool skipValidation);  
        10: }
        11:  
        12: public interface IEnumerableValueProvider : IValueProvider
        13: {
        14:     IDictionary<string, string> GetKeysFromPrefix(string prefix);
        15: }
        16:  
        17: public interface IUnvalidatedValueProvider : IValueProvider
        18: {
        19:     ValueProviderResult GetValue(string key, bool skipValidation);
        20: }

      從上面的代碼片斷我們可以看到,除了IValueProvider接口,NameValueCollectionValueProvider還實現了IEnumerableValueProvider和IUnvalidatedValueProvider兩個接口。顧名思義,IEnumerableValueProvider主要用于針對目標類型為集合的數據提供,方法GetKeysFromPrefix以一字典的形式返回具有指定前綴的Key。在默認的情況下,在進行數據提供的同時會對數據進行驗證,而IUnvalidatedValueProvider接口提供了一個額外的GetValue方法是我們可以忽略對數據的驗證。

      三、兩種前綴形式

      輔助實現Model綁定的數據提供機制是以Model元數據為基礎的,通過《初識Model元數據》我們知道用于描述一個復雜數據類型的Model元數據具有一個樹型的層次化結構,而作為數據源的NameValueCollection卻是一個“扁平”的結構,兩者之前的匹配通過前綴來表示。舉個簡單的例子,假設通過NameValueCollectionValueProvider提供對象的目標類型為具有如下定義的Contact。表示聯系地址的屬性是一個復雜類型Address,所以針對Contact類型的Model元數據樹具有兩個層級。

         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: }

      由于NameValueCollection中每個元數據的值都是一個字符串,所以不可能單獨表示一個復雜類型,復雜類型對象需要通過多個元素值組裝而成。如果通過NameValueCollectionValueProvider來初始化一個完整的Contact對象,表示數據源的NameValueCollection至少需要包含7個元素,分別針對Contact除Address屬性的三個屬性值和作為Address的四個屬性值,兩類元素在NameValueCollection中通過基于屬性的前綴來區分,具體的結構如下所示。

         1: Name:Foo
         2: PhoneNo:123456789
         3: EmailAddress:Foomail.com
         4: Address.Province: 江蘇
         5: Address.City: 蘇州
         6: Address.District: 工業園區
         7: Address.Street: 星湖街328號

      將點號(.)作為分隔符的前綴除了表示基于屬性的層級關系之外,還可以用于數據篩選。如下面的代碼片斷所示,我們在ContactController中定義了一個用于添加聯系人的AddContacts,它具有兩個Contact類型的參數foo和bar,表示添加的兩個不同的聯系人。

         1: public class ContactController
         2: {
         3:     public void AddContacts(Contact foo, Contact bar)
         4:     { 
         5:         //省略實現
         6:     }
         7: }

      如果我們采用NameValueCollectionValueProvider來提供作為AddContacts方法參數的兩個Contact對象,保存在NameValueCollection的數據元素必須能夠與它們進行合理映射。一般情況下這可以通過針對參數名的前綴來實現,具體數據結構如下所示。

         1: foo.Name:Foo
         2: foo.PhoneNo:123456789
         3: foo.EmailAddress:Foo@gmail.com
         4: foo.Address.Province: 江蘇
         5: foo.Address.City: 蘇州
         6: foo.Address.District: 工業園區
         7: foo.Address.Street: 星湖街328號
         8:  
         9: bar.Name:Bar
        10: bar.PhoneNo:987654321
        11: bar.EmailAddress:Bar@gmail.com
        12: bar.Address.Province: 江蘇
        13: bar.Address.City: 蘇州
        14: bar.Address.District: 工業園區
        15: bar.Address.Street: 機場路328號

      除了采用基于“.”的前綴之外,數組或者集合類型的數據源元素可以采用基于“索引”的前綴,這樣的前綴通過方括號“[]”表示,如下的數據結構就可以表示包含兩個元素的Contact數組或者集合。

         1: [0].Name:Foo
         2: [0].PhoneNo:123456789
         3: [0].EmailAddress:Foo@gmail.com
         4: ...
         5: [1].Name:Bar
         6: [1].PhoneNo:987654321
         7: [1].EmailAddress:Bar@gmail.com
         8: ...
         9:  

      除了采用數字作為索引之前,我們還可以按照如下的方式通過文字作為索引。針對兩種不同形式的索引的Model綁定機制有所不同,我們會在后續的部分予以講述。

         1: [foo].Name:Foo
         2: [foo].PhoneNo:123456789
         3: [foo].EmailAddress:Foo@gmail.com
         4: ...
         5: [bar].Name:Bar
         6: [bar].PhoneNo:987654321
         7: [bar].EmailAddress:Bar@gmail.com
         8: ...

      如果數據源元素針對不同的目標集合對象,同樣需要采用相應的前綴予以區分,相面的數據結構可以看成是針對兩個Contact列表(first和second)的數據源。

         1: first[0].Name:Zhao
         2: first[0].PhoneNo:12
         3: first[0].EmailAddress:zhao @gmail.com
         4: ...
         5: first[1].Name:Qian
         6: first[1].PhoneNo:34
         7: first[1].EmailAddress:qian@gmail.com
         8: ...
         9:  
        10: second[0].Name:Sun
        11: second[0].PhoneNo:56
        12: second[0].EmailAddress:sun@gmail.com
        13: ...
        14: second[1].Name:Li
        15: second[1].PhoneNo:78
        16: second[1].EmailAddress:li@gmail.com

      四、實例演示:返回指定前綴的Key

      在了解兩種不同類型的前綴之后,我們來關注一下NameValueCollectionValueProvider實現的GetKeysFromPrefix方法。從該方法的定義可以看出它返回的是一個IDictionary<string, string>對象,但是這個對象具有怎樣的數據呢?我們為此來進行一個實例演示。在通過Visual Studio的ASP.NET MVC項目模板創建的空Web應用中,我們定義了如下一個默認的HomeController。在Action方法Index中我們創建了一個NameValueCollection對象,并針對它創建一個NameValueCollectionValueProvider.

         1: public class HomeController : Controller
         2: {
         3:     public void Index()
         4:     {
         5:         NameValueCollection datasource = new NameValueCollection();
         6:         datasource.Add("foo.Name", "Foo");
         7:         datasource.Add("foo.PhoneNo", "123456789");
         8:         datasource.Add("foo.EmailAddress", "Foo@gmail.com");
         9:         datasource.Add("foo.Address.Province", "江蘇");
        10:         datasource.Add("foo.Address.City", "蘇州");
        11:         datasource.Add("foo.Address.District", "工業園區");
        12:         datasource.Add("foo.Address.Street", "星湖街328號");
        13:         NameValueCollectionValueProvider valueProvider = new NameValueCollectionValueProvider(datasource, CultureInfo.InvariantCulture);
        14:  
        15:         var keyDictionary = valueProvider.GetKeysFromPrefix("foo");
        16:         Response.Write("foo<br/>");
        17:         foreach (var item in keyDictionary)
        18:         {
        19:             Response.Write(string.Format("{0}: {1}<br/>", item.Key, item.Value));
        20:         }
        21:  
        22:         keyDictionary = valueProvider.GetKeysFromPrefix("foo.Address");
        23:         Response.Write("<br/>foo.Address<br/>");
        24:         foreach (var item in keyDictionary)
        25:         {
        26:             Response.Write(string.Format("{0}: {1}<br/>", item.Key, item.Value));
        27:         }
        28:     }
        29: }

      通過上面的代碼片斷可以看出,作為NameValueCollectionValueProvider的數據元素是按照Contact類型的屬性定義來添加的。我們分別將“foo”和“foo.Address”作為前綴返回以此作為前綴的Key。運行該程序后會在瀏覽器上得到如下的輸出結果。我們可以看到對于針對指定前綴返回的字典對象,其Key和Value的不同之處在于前者沒有包含指定的前綴而后者包含。此外,字典對象包含的元素全部處于同一級別,將“foo”指定為前綴時返回的元素針對于Contact的四個屬性。雖然NameValueCollection中并不包含一個名為“foo.Address”的元素,但是依然會將其單獨作為以“foo”為前綴的Key。

         1: foo
         2: Name            : foo.Name
         3: PhoneNo         : foo.PhoneNo
         4: EmailAddress    : foo.EmailAddress
         5: Address         : foo.Address
         6:  
         7: foo.Address
         8: Province        : foo.Address.Province
         9: City            : foo.Address.City
        10: District        : foo.Address.District
        11: Street          : foo.Address.Street

      接下來我們采用相應的方式來演示基于索引的前綴,為此我們將HomeController的Index反方法進行了如下的改寫。作為數據源的NameValueCollection對象針對一個包含兩個元素的Contact集合,前綴“first”可以作為集合對象的名稱。

         1: public class HomeController : Controller
         2: {
         3:     public void Index()
         4:     {
         5:         NameValueCollection datasource = new NameValueCollection();
         6:         datasource.Add("first[0].Name", "Foo");
         7:         datasource.Add("first[0].PhoneNo", "123456789");
         8:         datasource.Add("first[0].EmailAddress", "Foo@gmail.com");
         9:  
        10:         datasource.Add("first[1].Name", "Bar");
        11:         datasource.Add("first[1].PhoneNo", "987654321");
        12:         datasource.Add("first[1].EmailAddress", "Bar@gmail.com");
        13:         NameValueCollectionValueProvider valueProvider = new NameValueCollectionValueProvider(datasource, CultureInfo.InvariantCulture);
        14:  
        15:         var keyDictionary = valueProvider.GetKeysFromPrefix("first");
        16:         Response.Write("first<br/>");
        17:         foreach (var item in keyDictionary)
        18:         {
        19:             Response.Write(string.Format("{0}: {1}<br/>", item.Key, item.Value));
        20:         }
        21:  
        22:         keyDictionary = valueProvider.GetKeysFromPrefix("first[0]");
        23:         Response.Write("<br/>first[0]<br/>");
        24:         foreach (var item in keyDictionary)
        25:         {
        26:             Response.Write(string.Format("{0}: {1}<br/>", item.Key, item.Value));
        27:         }
        28:  
        29:         keyDictionary = valueProvider.GetKeysFromPrefix("first[1]");
        30:         Response.Write("<br/>first[1]<br/>");
        31:         foreach (var item in keyDictionary)
        32:         {
        33:             Response.Write(string.Format("{0}: {1}<br/>", item.Key, item.Value));
        34:         }
        35:     }
        36: }

      我們分別針對三個前綴“first”、“first[0]”和“first[1]”獲取相應字典對象并將其Key和Value呈現出來。該程序執行之后會在瀏覽器中產生如下的輸出,如果我們將“[”和“]”視為和”.”一樣的分割符,GetKeysFromPrefix針對索引作為前綴的規則與基于“.”前綴的規則沒有本質的區別。

         1: first
         2: 0: first[0]
         3: 1: first[1]
         4:  
         5: first[0]
         6: Name        : first[0].Name
         7: PhoneNo     : first[0].PhoneNo
         8: EmailAddress: first[0].EmailAddress
         9:  
        10: first[1]
        11: Name        : first[1].Name
        12: PhoneNo     : first[1].PhoneNo
        13: EmailAddress: first[1].EmailAddress

      五、FormValueProvider與QueryStringValueProvider

      在ASP.NET MVC 應用編程接口中,NameValueCollectionValueProvider具有兩個繼承者,即FormValueProviderQueryStringValueProvider。對于FormValueProvider來說,最終作為數據源的NameValueCollection對象通過請求表單創建,Name和Value分別來源于表單元素的名稱和值,它的定義基本上可以通過如下的代碼表示(實際定義有所差異)。

         1: public sealed class FormValueProvider : NameValueCollectionValueProvider
         2: {
         3:     public FormValueProvider(ControllerContext controllerContext)
         4:         : base(controllerContext.RequestContext.HttpContext.Request.Form, CultureInfo.CurrentCulture)
         5:     { }
         6: }

      對于QueryStringValueProvider來說,無須多說,其作為數據源的NameValueCollection對象愛那個自然來源于請求的查詢字符串,其定義基本上可以通過如下的代碼表示(實際定義有所差異)。

         1: public sealed class QueryStringValueProvider: NameValueCollectionValueProvider
         2: {
         3:     public NameValueCollection(ControllerContext controllerContext)
         4:         : base(controllerContext.RequestContext.HttpContext.Request.QueryString, CultureInfo.CurrentCulture)
         5:     { }
         6: }

       

      ASP.NET MVC以ValueProvider為核心的值提供系統: NameValueCollectionValueProvider
      ASP.NET MVC以ValueProvider為核心的值提供系統: DictionaryValueProvider
      ASP.NET MVC以ValueProvider為核心的值提供系統: ValueProviderFactory

      posted @ 2012-05-17 09:04  Artech  閱讀(8018)  評論(6)    收藏  舉報
      主站蜘蛛池模板: 亚洲av日韩av综合在线观看| 久久精品国产熟女亚洲av| 天堂mv在线mv免费mv香蕉| 乱妇乱女熟妇熟女网站| 成人亚欧欧美激情在线观看| 国产精品人成在线观看免费| 人妻少妇久久久久久97人妻| 国产高清亚洲一区亚洲二区| 亚洲精品成人7777在线观看| 国语精品国内自产视频| 国产三级a三级三级| 色综合中文字幕色综合激情| 亚洲一二三区精品美妇| 亚洲中文字幕一区二区| 最新精品国偷自产在线美女足| 女人与公狍交酡女免费| 欧美性xxxxx极品| 97人妻天天爽夜夜爽二区| 亚洲精品中文字幕第一页| 亚洲日本欧洲二区精品| 午夜自产精品一区二区三区| 亚洲中文字幕无码爆乳app| 日韩深夜福利视频在线观看| 麻豆一区二区中文字幕| 国产无遮挡又黄又爽免费网站| 高清破外女出血AV毛片| 久久青青草原精品国产app| 国产av第一次处破| 久久国产精品精品国产色| 国产成人片无码视频在线观看| 久久精品国产99麻豆蜜月| 欧美性猛交xxxx乱大交丰满| 久久天天躁狠狠躁夜夜婷 | 亚洲第一区二区快射影院| 97久久精品无码一区二区天美| 精品人妻午夜福利一区二区| 亚洲av永久无码精品天堂久久| 少妇办公室好紧好爽再浪一点| 香蕉久久夜色精品国产成人| 亚洲少妇人妻无码视频| 国产精品小仙女自拍视频|