ASP.NET Web API Model-ValueProvider

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

圖1ide

 

IValueProvider接口類型--ValueProvider行爲約束函數

 首先咱們看一下圖1中右邊的部分,起頭的就是一個IValueProvider接口類型,咱們就來看一下接口的定義:ui

示例代碼1-1spa

    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接口類型的定義,這個接口主要負責什麼呢?code

 

IEnumerableValueProvider接口類型-ValueProvider行爲約束對象

 示例代碼1-2blog

    public interface IEnumerableValueProvider : IValueProvider
    {
        IDictionary<string, string> GetKeysFromPrefix(string prefix);
    }

從代碼1-2中能夠很清楚明瞭的看到IEnumerableValueProvider接口類型的職責很簡單,就是對指定的前綴值進行檢索,而且最後以鍵值隊的形式返回,這個在下面會有示例詳細說明。接口

 

NameValuePairsValueProvider類型-ValueProvider基礎結構ip

示例代碼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/

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面

相關文章
相關標籤/搜索