標籤:style blog http color io os 使用 ar strong
ASP.NET Web API Model-ValueProvider前言
前面一篇講解了Model中繼資料,Model中繼資料是在Model綁定中很重要的一部分,只是Model綁定中涉及的知識點比較多,對於ASP.NET MVC架構來說ASP.NET Web API架構中在Model綁定部分又新增了參數綁定這麼一個機制,這些內容都會在後面的篇幅中說明,前面的這些篇幅都是講解理論上的知識也沒有涉及到樣本的示範,這個大家不用急在最後Model部分的基礎知識講解完之後我會把前面所講的全部串聯起來,而今天這個篇幅給大家帶來的就是在Model綁定中起到至關重要的一個環節,大家這個不用去管什麼Model綁定,而是單純的去瞭解ValueProvider這一系列的物件模型,因為在沒有結合前後知識點串聯起來之前,我們都不知道ValueProvider是在哪執行的。所以我們還是老老實實瞭解一下ValueProvider相關的對象吧。
Model-ValueProvider
圖1
IValueProvider介面類型--ValueProvider行為約束
首先我們看一1中右邊的部分,起頭的就是一個IValueProvider介面類型,我們就來看一下介面的定義:
範例程式碼1-1
public interface IValueProvider { bool ContainsPrefix(string prefix); ValueProviderResult GetValue(string key); }
我們在代碼1-1中看到,IValueProvider介面中定義了兩個方法,一個是ContainsPrefix()方法,接收string類型的參數並且返回的是bool實值型別,這個方法表示的就是根據指定的首碼值查看當前的ValueProvider中是否存在這個首碼值,這個下面會有樣本稍後再說,然後就是GetValue()方法,是根據執行的索引值返回當中的對應的值,從這裡一看我們就大概能猜到這個ValueProvider應該是類似於索引值隊一樣的類型,而返回的結果被封裝在了ValueProviderResult類型當中,這個類型稍後會有說明。在IValueProvider介面約束好ValueProvider值提供者的行為後,我們應該就來看一看ValueProvider值提供者的基礎結構了。不過呢在此之前我們還是要根據圖1中所示的那樣,先來看一下IEnumerableValueProvider介面類型的定義,這個介面主要負責什麼呢?
IEnumerableValueProvider介面類型-ValueProvider行為約束
範例程式碼1-2
public interface IEnumerableValueProvider : IValueProvider { IDictionary<string, string> GetKeysFromPrefix(string prefix); }
從代碼1-2中可以很清楚明了的看到IEnumerableValueProvider介面類型的職責很簡單,就是對指定的首碼值進行檢索,並且最後以索引值隊的形式返回,這個在下面會有樣本詳細說明。
NameValuePairsValueProvider類型-ValueProvider基礎結構
範例程式碼1-3
public class NameValuePairsValueProvider : IEnumerableValueProvider, IValueProvider { public NameValuePairsValueProvider(Func<IEnumerable<KeyValuePair<string, string>>> valuesFactory, CultureInfo culture); public NameValuePairsValueProvider(IEnumerable<KeyValuePair<string, string>> values, CultureInfo culture); public virtual bool ContainsPrefix(string prefix); public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix); public virtual ValueProviderResult GetValue(string key); }
在代碼1-3中我們看到NameValuePairsValueProvider類型的定義,首先就說說它的建構函式吧,兩個建構函式的區別在於第一個是Func<IEnumerable<KeyValuePair<string, string>>>類型的建構函式參數,第二個是IEnumerable<KeyValuePair<string, string>>類型的建構函式參數,第二個建構函式的首個參數類型實際就是第一個建構函式首個參數的傳回型別,這裡大家都看得到,其實在內部實現,也是這樣的聲明第一個建構函式是沒什麼的,聲明第二個建構函式的時候其實就把參數再次封裝為委託。
對於KeyValuePair<T,U>類型可以理解為索引值隊的子項,在它的類型中只有一個索引值對應一個值只有一項就是它本身。
至於剩下的三個方法我們還是靠簡單的樣本來說明一下。
範例程式碼1-4
public class ValueProviderCaseController : ApiController { public string Get() { KeyValuePair<string,string>[] dictionary=new KeyValuePair<string,string>[] { new KeyValuePair<string,string>("EmployeesInfo.Name","Jinyuan"), new KeyValuePair<string,string>("EmployeesInfo.Age","24"), new KeyValuePair<string,string>("EmployeesInfo.Sex","男"), new KeyValuePair<string,string>("EmployeesInfo.AddressInfo.AddressInfo","南京市"), new KeyValuePair<string,string>("EmployeesInfo.AddressInfo.ZipCode","210000") }; NameValuePairsValueProvider nameValuePairsValueProvider=new NameValuePairsValueProvider(dictionary,null); StringBuilder strBuilder = new StringBuilder(); NameValuePairsPrefixAnalysis(strBuilder, nameValuePairsValueProvider, "EmployeesInfo"); return strBuilder.ToString(); } private void NameValuePairsPrefixAnalysis(StringBuilder stringbuilder, NameValuePairsValueProvider namevaluepairs,string prefix) { IDictionary<string, string> dictionarys = namevaluepairs.GetKeysFromPrefix(prefix); if (dictionarys.Count > 0) { Console.WriteLine(prefix + "為首碼的資料來源Key值檢索……"); foreach (var item in dictionarys) { Console.WriteLine("Key:" + item.Key + " Value:" + item.Value); } foreach (KeyValuePair<string, string> keyvalue in dictionarys) { NameValuePairsPrefixAnalysis(stringbuilder, namevaluepairs, keyvalue.Value); } } else { stringbuilder.AppendLine(prefix+":"+ namevaluepairs.GetValue(prefix).RawValue.ToString()); } }}
我們來看代碼1-4,首先我在Get()方法中定義了一個KeyValuePair<string,string>[]類型,為了能夠執行個體化NameValuePairsValueProvider類型,在此之後大家可以看到我調用了一個我自訂的NameValuePairsPrefixAnalysis()方法,並且在其中使用NameValuePairsValueProvider類型的執行個體調用了GetKeysFromPrefix()方法,也就是代碼1-2所約束的那個行為。這個時候我們先來看一下表1.
表1
Key |
Value |
EmployeesInfo.Name |
Jinyuan |
EmployeesInfo.Age |
24 |
EmployeesInfo.Sex |
男 |
EmployeesInfo.AddressInfo.AddressInfo |
南京市 |
EmployeesInfo.AddressInfo.ZipCode |
210000 |
表1所表示的就是初始資料來源,也就是我們定義的KeyValuePair<string,string>[]類型的鍵、值示意表。
然而在我們使用NameValuePairsValueProvider類型的執行個體已” EmployeesInfo”作為首碼調用了GetKeysFromPrefix()方法後返回的IDictionary<string, string>類型的值如表2.
表2
Key |
Value |
Name |
EmployeesInfo.Name |
Age |
EmployeesInfo.Age |
Sex |
EmployeesInfo.Sex |
AddressInfo |
EmployeesInfo.AddressInfo |
這裡的表2值只是第一層的關係值。
在此之後我們輸出的當前的所要檢索的首碼值以及檢索過後的值,並且會遍曆表2裡的Value值作為首碼值再次的對資料來源進行首碼檢索,如果沒有了則說明已經沒有可檢索的了。
並且使用NameValuePairsValueProvider類型執行個體調用的GetValue()方法根據最後已經檢索不出來有尾碼的首碼值,也就是未經處理資料源當中的Key值了。
最後我們看一下結果。
圖2
在用戶端我們擷取到了值,當然這裡只是示範樣本,值提供者提供的值方向反了。
然後我們可以在服務端看到檢索的記錄,可以明確的看到有兩層的結構在其中。有興趣的朋友深入一下看下檢索的具體實現方式。
QueryStringValueProvider類型-ValueProvider特定結構
範例程式碼1-5
public class QueryStringValueProvider : NameValuePairsValueProvider { public QueryStringValueProvider(HttpActionContext actionContext, CultureInfo culture) : base(func, culture) { Func<IEnumerable<KeyValuePair<string, string>>> func = null; if (func == null) { func = () => actionContext.ControllerContext.Request.GetQueryNameValuePairs(); } } }
從代碼1-5中可以看到在QueryStringValueProvider類型初始化的時候建構函式中的執行,把從請求查詢字串作為未經處理資料來源封裝為委託類型,然後調用基類的建構函式。
RouteDataValueProvider類型-ValueProvider特定結構
範例程式碼1-6
public class RouteDataValueProvider : NameValuePairsValueProvider { public RouteDataValueProvider(HttpActionContext actionContext, CultureInfo culture) : base(func, culture) { Func<IEnumerable<KeyValuePair<string, string>>> func = null; if (func == null) { func = () => GetRoutes(actionContext.ControllerContext.RouteData); } } }
同上面1-5一樣的道理,這裡使用了HttpRouteData中的Values值作為未經處理資料源。
還有圖1中的左邊部分會在後面的篇幅中講解,在這裡講不適合,會感覺不連貫,雖然看完本篇不知道這個起到了什麼作用也不知道怎麼去使用,感覺被掐住了脖子一樣的難受,但是後面我會把前面所講的內容全部串聯起來做一個示範,所示這是基礎部分的知識,就是一個鋪墊。
金源
出處:http://www.cnblogs.com/jin-yuan/
本文著作權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面
ASP.NET Web API Model-ValueProvider