天天看點

ASP.NET MVC以ValueProvider為核心的值提供系統: NameValueCollectionValueProvider一、IValueProvider與ValueProviderResult二、NameValueCollectionValueProvider三、兩種字首形式四、執行個體示範:傳回指定字首的Key五、FormValueProvider與QueryStringValueProvider

在進行Model綁定過程中,需要根據基于Action方法參數的綁定上下文從請求資料中提取相應的資料以提供相應的資料。具體來說,Model綁定的資料具有多個來源,可能來源于Post的表單或者JSON字元串,或者來源于目前的路由資料,也可能來源于請求位址的插叙字元串。ASP.NET

目錄 一、IValueProvider與ValueProviderResult 二、NameValueCollectionValueProvider 三、兩種字首形式 四、執行個體示範:傳回指定字首的Key 五、FormValueProvider與QueryStringValueProvider

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

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

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

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

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

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

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

如果資料源元素針對不同的目标集合對象,同樣需要采用相應的字首予以區分,相面的資料結構可以看成是針對兩個Contact清單(first和second)的資料源。

在了解兩種不同類型的字首之後,我們來關注一下NameValueCollectionValueProvider實作的GetKeysFromPrefix方法。從該方法的定義可以看出它傳回的是一個IDictionary<string,

string>對象,但是這個對象具有怎樣的資料呢?我們為此來進行一個執行個體示範。在通過Visual Studio的ASP.NET

MVC項目模闆建立的空Web應用中,我們定義了如下一個預設的HomeController。在Action方法Index中我們建立了一個NameValueCollection對象,并針對它建立一個NameValueCollectionValueProvider.

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

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

我們分别針對三個字首“first”、“first[0]”和“first[1]”擷取相應字典對象并将其Key和Value呈現出來。該程式執行之後會在浏覽器中産生如下的輸出,如果我們将“[”和“]”視為和”.”一樣的分割符,GetKeysFromPrefix針對索引作為字首的規則與基于“.”字首的規則沒有本質的差別。

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

<a href="http://www.cnblogs.com/artech/archive/2012/05/17/value-provider-01.html">ASP.NET MVC以ValueProvider為核心的值提供系統: NameValueCollectionValueProvider</a>

<a href="http://www.cnblogs.com/artech/archive/2012/05/18/value-provider-02.html">ASP.NET MVC以ValueProvider為核心的值提供系統: DictionaryValueProvider</a>

<a href="http://www.cnblogs.com/artech/archive/2012/05/19/value-provider-03.html">ASP.NET MVC以ValueProvider為核心的值提供系統: ValueProviderFactory</a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2012/05/17/value-provider-01.html" target="_blank">原文連結</a>

繼續閱讀