<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為核心的值提供系統(tǒng): DictionaryValueProvider

      NameValueCollectionValueProvider采用一個NameValueCollection作為數(shù)據(jù)源,DictionnaryValueProvider的數(shù)據(jù)源類型自然就是一個Dictionnary。NameValueCollection和Dictionnary都是一個鍵值對的集合,它們之間的不同之處在NameValueCollection運行元素具有相同的Key,Dictionnary卻要求元素的Key具有唯一性。[本文已經(jīng)同步到《How ASP.NET MVC Works?》中]

      目錄
      一、DictionaryValueProvider<TValue>
      二、RouteDataValueProvider
      三、HttpFileCollectionValueProvider
      四、ChildActionValueProvider
      五、實例演示:ChildActionValueProvider的值提供機制
      六、ValueProviderCollection

      一、DictionaryValueProvider<TValue>

      DictionnaryValueProvider的類型全名為System.Web.Mvc.DictionaryValueProvider<TValue>,如下面的代碼片斷所示,DictionaryValueProvider<TValue>實現(xiàn)了IEnumerableValueProvider和IValueProvider接口,構(gòu)造函數(shù)接受一個IDictionary<string, TValue>對象,該對象表示作為數(shù)據(jù)源的字典。定義在DictionaryValueProvider<TValue>中所有方法的邏輯與定義在NameValueCollectionValueProvider中的同名方法并沒有本質(zhì)區(qū)別。

         1: public class DictionaryValueProvider<TValue> : IEnumerableValueProvider, IValueProvider
         2: {
         3:     public DictionaryValueProvider(IDictionary<string, TValue> dictionary, CultureInfo culture);
         4:     public virtual bool ContainsPrefix(string prefix);
         5:     public virtual IDictionary<string, string> GetKeysFromPrefix(string prefix);
         6:     public virtual ValueProviderResult GetValue(string key);
         7: }

      二、RouteDataValueProvider

      將當(dāng)前路由數(shù)據(jù)作為數(shù)據(jù)源的RouteDataValueProvider繼承自DictionaryValueProvider<TValue>。如下面的代碼片斷所示,基于當(dāng)前Controller上下文構(gòu)建的RouteDataValueProvider直接將表示當(dāng)前路由數(shù)據(jù)的RouteData對象的Values屬性(這是一個RouteValueDictionary對象)作為數(shù)據(jù)來源。

         1: public sealed class RouteDataValueProvider : DictionaryValueProvider<object>
         2: {
         3:     public RouteDataValueProvider(ControllerContext controllerContext) : 
         4:         base(controllerContext.RouteData.Values, CultureInfo.InvariantCulture)
         5:     {
         6:     }
         7: }

      三、HttpFileCollectionValueProvider

      我們可以通過類型為file的輸入元素進行文件的上傳,在表示HTTP請求的HttpRequestBase對象中,上傳文件通過只讀屬性Files表示。從下面的代碼片斷所示,該屬性類型為HttpFileCollectionBase,是一個元素類型為HttpPostedFileBase的集合。

         1: public abstract class HttpRequestBase
         2: {   
         3:     public virtual HttpFileCollectionBase Files { get; }
         4: }
         5: public abstract class HttpFileCollectionBase : NameObjectCollectionBase, ICollection, IEnumerable
         6: {   
         7:     public virtual string[] AllKeys { get; }
         8:     public override int Count { get; }
         9:     public virtual HttpPostedFileBase this[int index] { get; }
        10:     public virtual HttpPostedFileBase this[string name] { get; }
        11: }
        12: public abstract class HttpPostedFileBase
        13: {
        14:     public virtual void SaveAs(string filename);
        15:  
        16:     public virtual int ContentLength { get; }
        17:     public virtual string ContentType { get; }
        18:     public virtual string FileName { get; }
        19:     public virtual Stream InputStream { get; }
        20: }

      用于處理上傳文件的Action方法通常定義類型為HttpPostedFileBase及其列表的參數(shù)來表示上傳的文件,針對HttpPostedFileBase參數(shù)的Model綁定選用的數(shù)據(jù)就來源于表示當(dāng)前請求的HttpRequestBase的Files屬性,而具體參數(shù)值的提供最終通過具有如下定義的HttpFileCollectionValueProvider來實現(xiàn)。

         1: public sealed class HttpFileCollectionValueProvider : DictionaryValueProvider<HttpPostedFileBase[]>
         2: {    
         3:     public HttpFileCollectionValueProvider(ControllerContext controllerContext);
         4: }

      如上面的代碼所示,HttpFileCollectionValueProvider繼承自DictionaryValueProvider<TValue>,泛型參數(shù)TValue的類型為HttpPostedFileBase數(shù)組,這是因為在同一個表單中可以定義多個同名的文件輸入元素,所以在以文件元素名稱作為Key的字典中,字典元素的值自然就是一個HttpPostedFileBase的列表。

      為了讓讀者對HttpFileCollectionValueProvider采用的針對上傳文件的值對象提供機制具有一個深刻的認識,我們來進行一個簡單的實例演示。在通過Visual Studio的ASP.NET MVC項目模板創(chuàng)建的空Web應(yīng)用中創(chuàng)建一個具有如下定義的HomeController。該Controller類型中定義了兩個Action方法,默認的Index方法會將默認的View呈現(xiàn)出來,DisplayPostedFiles方法則通過創(chuàng)建的HttpFileCollectionValueProvider對象將上傳文件的文件名稱呈現(xiàn)出來。

         1: public class HomeController : Controller
         2: {
         3:     public ActionResult Index()
         4:     {
         5:         return View();
         6:     }
         7:     [HttpPost]
         8:     public void DisplayPostedFiles()
         9:     {
        10:         HttpFileCollectionValueProvider valueProvider = new HttpFileCollectionValueProvider(ControllerContext);
        11:         IEnumerable<HttpPostedFileBase> foo = (IEnumerable<HttpPostedFileBase>)valueProvider.GetValue("foo").ConvertTo(typeof(IEnumerable<HttpPostedFileBase>));
        12:         IEnumerable<HttpPostedFileBase> bar =  (IEnumerable<HttpPostedFileBase>)valueProvider.GetValue("bar").ConvertTo(typeof(IEnumerable<HttpPostedFileBase>));
        13:  
        14:         Response.Write("foo<br/>");
        15:         foreach (var file in foo)
        16:         {
        17:             Response.Write(file.FileName + "<br/>");
        18:         }
        19:  
        20:         Response.Write("<br/>bar<br/>");
        21:         foreach (var file in bar)
        22:         {
        23:             Response.Write(file.FileName + "<br/>");
        24:         }            
        25:     }
        26: }

      在DisplayPostedFiles方法中,我們針對當(dāng)前Controller上下文創(chuàng)建HttpFileCollectionValueProvider對象,然后分別將字符“foo”和“bar”作為Key得到兩個HttpPostedFileBase對象列表,并將它們的文件名打印出來。下面的代碼表示Action方法Index對應(yīng)的View。在一個針對Action方法DisplayPostedFiles的表單中我們定義了三個文件輸入元素,其中前兩個名稱為“foo”和“bar”。

         1: @{
         2:    using(Html.BeginForm("DisplayPostedFiles","Home", 
         3:        FormMethod.Post,new {enctype="multipart/form-data"}))
         4:    {
         5:        <ul>
         6:         <li>File 1: <input type="file" name="foo"/></li>
         7:         <li>File 2: <input type="file"  name="foo"/></li>
         8:         <li>File 3: <input type="file"  name="bar"/></li>
         9:        </ul>  
        10:        <input type="submit" value="提交" />       
        11:     }
        12: }

      當(dāng)我們運行該程序的時候,瀏覽器上會出現(xiàn)一個包含三個文件輸入元素和提交按鈕的頁面。然后我們從本地選擇任意三個文件(比如text1.txt、text2.txt和text2.txt)并點擊“提交”按鈕,界面上會出現(xiàn)如下所示的輸出結(jié)果。

         1: foo
         2: text1.txt
         3: text2.txt
         4:  
         5: bar
         6: text3.txt

      四、ChildActionValueProvider

      子Action和普通意義上的Action的不同之處在于它不能用于響應(yīng)來自客戶端的請求,而在某個View中被調(diào)用以生成某個部分的HTML。View中針對某個子Action方法的調(diào)用通過如下所示的HtmlHelper的擴展方法Action來實現(xiàn)。

         1: public static class ChildActionExtensions
         2: {
         3:     //其他成員
         4:     public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName);
         5:     public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, object routeValues);
         6:     public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName);
         7:     public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues);
         8:     public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues);
         9:     public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues);  
        10: }

      顧名思義,ChildActionValueProvider專門服務(wù)于針對子Action方法參數(shù)的Model綁定。如下面的代碼片斷所示,ChildActionValueProvider依然是DictionaryValueProvider<TValue>的繼承者,不過這里的泛型參數(shù)類型Object。那么在作為數(shù)據(jù)源的字典中,具體的Key和Value究竟是怎樣一個對象呢?

         1: public sealed class ChildActionValueProvider : DictionaryValueProvider<object>
         2: {
         3:     public ChildActionValueProvider(ControllerContext controllerContext);
         4:     public override ValueProviderResult GetValue(string key);
         5: }

      當(dāng)我們創(chuàng)建針對指定的Controller上下文創(chuàng)建一個ChildActionValueProvider對象時,會獲取描述針對該上下文路由信息的RouteData對象,并將其Values屬性表示的RouteValueDictionary對象作為其數(shù)據(jù)源,這可以從如下所示的ChildActionValueProvider的構(gòu)造函數(shù)定義看出來。

         1: public sealed class ChildActionValueProvider : DictionaryValueProvider<object>
         2: {
         3:     //其他成員   
         4:     public ChildActionValueProvider(ControllerContext controllerContext) :  base(controllerContext.RouteData.Values, CultureInfo.InvariantCulture)
         5:     {
         6:     }
         7: }

      但是ChildActionValueProvider的GetValue方法獲取的值卻并不是簡單地來源于構(gòu)造時針對當(dāng)前上下文的路由信息,不然ChildActionValueProvider就和RouteDataValueProvider沒有什么分別了。實際上,ChildActionValueProvider的GetValue方法獲取的值來源于調(diào)用HtmHelper的擴展方法Action時通過參數(shù)routeValues指定的RouteValueDictionary。

      現(xiàn)在我們來簡單介紹一下定義在ChildActionValueProvider的GetValue方法中的對象值的提供機制。如下面的代碼片斷所示,ChildActionValueProvider具有一個字符串類型的靜態(tài)字段_childActionValuesKey。當(dāng)該類型第一次被加載時,該字段被初始化成一個GUID。

         1: public sealed class ChildActionValueProvider : DictionaryValueProvider<object>
         2: {
         3:     //其他成員
         4:     private static string _childActionValuesKey = Guid.NewGuid().ToString();
         5: }

      在某個View中通過HtmlHelper的擴展方法Action執(zhí)行子Action方法時,如果通過參數(shù)routeValues指定的RouteValueDictionary不為空,會基于這個對象創(chuàng)建一個DictionaryValueProvider<TValue>對象。然后將這個對象添加到通過routeValues表示的原始的RouteValueDictionary對象中,對應(yīng)的Key就是ChildActionValueProvider的靜態(tài)屬性_childActionValuesKey表示的GUID。

      這個RouteValueDictionary被進一步封裝成表示請求上下文的RequestContext對象,目標子Action所在的Controller會在該請求上下文中被激活,而在Controller激活過程中表示Controller上下文的ControllerContext被創(chuàng)建出來,毫無疑問它包含了之前創(chuàng)建的RouteValueDictionary對象。而我們針對當(dāng)前Controller上下文創(chuàng)建ChildActionValueProvider的時候指定的作為數(shù)據(jù)源的RouteValueDictionary對象就是這么一個對象。

         1: @Html.Action("XxxChildAction", new {Foo=123, Bar = 456, Baz=789})

      舉個例子,假設(shè)我們在某個View中如果如下的方式調(diào)用當(dāng)前Controller的子Action方法 XxxChildAction,并指定相應(yīng)的路由數(shù)據(jù)(Foo、Bar和Baz)。最終作為ChildActionValueProvider數(shù)據(jù)源的Dictionary<string,object>對象結(jié)構(gòu)如下圖所示。

      image

      當(dāng)調(diào)用ChildActionValueProvider的GetValue方法獲取指定Key的值時,實際上并不會直接根據(jù)指定的Key去獲取對應(yīng)的值,而是根據(jù)通過其靜態(tài)字段_childActionValuesKey值去獲取對應(yīng)的DictionaryValueProvider<object>對象。然后再調(diào)用該對象的GetValue根據(jù)指定的Key去獲得相應(yīng)的值。

      五、實例演示:ChildActionValueProvider的值提供機制

      為了印證上面介紹的關(guān)于ChildActionValueProvider的值提供機制,我們來演示一個簡單的實例。在進行演示之前有一個點需要作一下簡單說明,對于DictionaryValueProvider<TValue>對象來說,最終作為其數(shù)據(jù)源的通過私有字段_values表示的一個Dictionary<string, ValueProviderResult對象。當(dāng)我們調(diào)用GetValue方法是,只需要根據(jù)指定的Key從該字典對象中返回相應(yīng)的ValueProviderResult即可。

         1: public class DictionaryValueProvider<TValue> : IEnumerableValueProvider, IValueProvider
         2: {
         3:     //其他成員
         4:     private readonly Dictionary<string, ValueProviderResult> _values;
         5: }

      在通過Visual Studio的ASP.NET MVC 項目模板創(chuàng)建的空Web應(yīng)用中定義如下一個默認的HomeController。默認的Action方法Index僅僅是將默認的View呈現(xiàn)出來而已,并沒有特別之處。在另一個Action方法DisplayRouteData中,我們名稱分別為Foo、Bar和Baz的三個路由數(shù)據(jù)篡改成“abc”、“ijk”和“zyz”。然后根據(jù)當(dāng)前Controller上下文創(chuàng)建一個ChildActionValueProvider對象,并通過反射的方式獲取通過它的私有字段_values表示的Dictionary<string, ValueProviderResult對象。

         1: public class HomeController : Controller
         2: {
         3:     public ActionResult Index()
         4:     {
         5:         return View();
         6:     }
         7:  
         8:     public ActionResult DisplayRouteData()
         9:     {
        10:         ControllerContext.RouteData.Values["Foo"] = "abc";
        11:         ControllerContext.RouteData.Values["Bar"] = "ijk";
        12:         ControllerContext.RouteData.Values["Baz"] = "xyz";
        13:  
        14:         StringBuilder sb = new StringBuilder();
        15:         ChildActionValueProvider valueProvider = new ChildActionValueProvider(ControllerContext);
        16:         FieldInfo valuesField = typeof(DictionaryValueProvider<object>).GetField("_values", BindingFlags.Instance|BindingFlags.NonPublic);
        17:         Dictionary<string, ValueProviderResult> values = (Dictionary<string, ValueProviderResult>)valuesField.GetValue(valueProvider);
        18:         foreach (string key in values.Keys)
        19:         {
        20:             sb.Append(string.Format("{0}: {1}<br/>", key, values[key].RawValue));
        21:             DictionaryValueProvider<object> innerValueProvider = values[key].RawValue as DictionaryValueProvider<object>;
        22:             if (innerValueProvider == null)
        23:             {
        24:                 continue;
        25:             }
        26:             sb.Append(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}: {1}<br/>", "Foo", innerValueProvider.GetValue("Foo").RawValue));
        27:             sb.Append(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}: {1}<br/>", "Bar", innerValueProvider.GetValue("Bar").RawValue));
        28:             sb.Append(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}: {1}<br/>", "Baz", innerValueProvider.GetValue("Baz").RawValue));
        29:         }
        30:  
        31:         sb.Append("<br/>ChildActionValueProvider.GetValue()<br/>");
        32:         sb.Append(string.Format("{0}: {1}<br/>", "Foo", valueProvider.GetValue("Foo").RawValue));
        33:         sb.Append(string.Format("{0}: {1}<br/>", "Bar", valueProvider.GetValue("Bar").RawValue));
        34:         sb.Append(string.Format("{0}: {1}<br/>", "Baz", valueProvider.GetValue("Baz").RawValue));            
        35:  
        36:         return Content(sb.ToString());
        37:     }
        38: }

      我們創(chuàng)建一個StringBuilder對象,并將用于輸出獲取到的Dictionary<string, ValueProviderResult>對象的Key和Value的HTML添加其中。在進行遍歷過程中,如果ValueProviderResult對象的RawValue屬性是一個DictionaryValueProvider<object>對象,則調(diào)用其GetValue方法得到Key分別為Foo、Bar和Baz的值。相應(yīng)的輸出的HTML一并添加到StringBuilder中。

      在程序的最后,我們直接調(diào)用ChildActionValueProvider的GetValue方法獲取針對Foo、Bar和Baz作為Key的值,并將輸出Key和Value的HTML添加到StringBuilder中。最終針對生成的HTML字符串返回一個ContentResult對象。如下所示的代碼反映Action方法Index對應(yīng)的View的定義,在這里我們直接調(diào)用HtmlHelper的擴展方法Action執(zhí)行定義在HomeController的Action方法DisplayRouteData,并指定了相應(yīng)的路由數(shù)據(jù)(Foo、Bar和Baz)。

         1: @Html.Action("DisplayRouteData", new { Foo = 123, Bar = 456, Baz = 789 })

      運行我們的程序會在瀏覽器中得到如下的輸出結(jié)果。我們可以從中看到針對于Controller和Action名稱的路由數(shù)據(jù)和調(diào)用HtmlHelper擴展方法Action指定的數(shù)據(jù)數(shù)據(jù)均在作為ChildActionValueProvider數(shù)據(jù)源的字典對象中。除此之外,還具有一個DictionaryValueProvider<object>對象,對應(yīng)的Key是一個GUID,這正是我們上面介紹的針對在HtmlHelper擴展方法Action中指定的路由數(shù)據(jù)創(chuàng)建的DictionaryValueProvider<object>對象,而調(diào)用GetValue方法獲取到的值最終是通過它提供的。

         1: Foo: abc
         2: Bar: ijk
         3: Baz: xyz
         4: controller: Home
         5: action: DisplayRouteData
         6: 289594f6-dfba-45b9-8abb-158b4a582911: 
         7:     System.Web.Mvc.DictionaryValueProvider`1[System.Object]
         8:     Foo: 123
         9:     Bar: 456
        10:     Baz: 789
        11:  
        12: ChildActionValueProvider.GetValue()
        13: Foo: 123
        14: Bar: 456
        15: Baz: 789

      六、ValueProviderCollection

      類型ValueProviderCollection不僅僅表示一個ValueProvider對象的集合,還作為一個單純的ValueProvider來使用。如下面的代碼片斷所示,ValueProviderCollection不僅僅繼承自Collection<IValueProvider>,還同時實現(xiàn)了IValueProvider、IEnumerableValueProvider和IUnvalidatedValueProvider三個接口。

         1: public class ValueProviderCollection : Collection<IValueProvider>, IUnvalidatedValueProvider, IEnumerableValueProvider, IValueProvider
         2: {
         3:     public ValueProviderCollection();
         4:     public ValueProviderCollection(IList<IValueProvider> list);
         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: }

      對于兩個實現(xiàn)值提供機制的GetValue方法重載來說,ValueProviderCollection會遍歷集合直到找到一個GetValue方法返回值不為Null的ValueProvider,而該返回值就是該方法的返回值。如果所有ValueProvider的GetValue方法均返回Null,則ValueProviderCollection的GetValue方法也為Null。也就是說,ValueProvider在集合中的先后次序決定了其使用優(yōu)先級

      如果有任何一個ValueProvider的ContainsPrefix方法返回True,則ValueProviderCollection的ContainsPrefix也返回True。GetKeysFromPrefix方法的邏輯與GetValue方法類似,它會遍歷作為集合中實現(xiàn)了IEnumerableValueProvider接口的所有ValueProvider對象,并將指定的前綴作為參數(shù)調(diào)用ContainsPrefix方法,如果返回值為True,則直接返回GetKeysFromPrefix方法的結(jié)果;否則返回一個空的Dictionary<string, string>對象。

      ASP.NET MVC以ValueProvider為核心的值提供系統(tǒng): NameValueCollectionValueProvider
      ASP.NET MVC以ValueProvider為核心的值提供系統(tǒng): DictionaryValueProvider
      ASP.NET MVC以ValueProvider為核心的值提供系統(tǒng): ValueProviderFactory

      posted @ 2012-05-18 08:22  Artech  閱讀(5683)  評論(8)    收藏  舉報
      主站蜘蛛池模板: 毛片亚洲AV无码精品国产午夜| 激情综合一区二区三区| 欧美成人精品高清在线播放| 99久久婷婷国产综合精品青草漫画| 一区二区中文字幕久久| 女人下边被添全过视频的网址| 永久黄网站色视频免费直播| 日韩av在线一区二区三区| 亚洲一精品一区二区三区| 日韩蜜桃AV无码中文字幕不卡高清一区二区 | 亚洲av专区一区| 日韩人妻精品中文字幕| 丁香五月亚洲综合深深爱| AV极品无码专区亚洲AV| 和平县| 四虎成人精品永久免费av| 亚洲国产色一区二区三区| 精品乱人伦一区二区三区| 乱人伦人妻系列| 国产乱码日韩精品一区二区| 亚洲国产色播AV在线| 日韩人妻无码一区二区三区99| 国产精品综合一区二区三区| 亚洲国内精品一区二区| 中文日产乱幕九区无线码| 色爱av综合网国产精品| 成人国产一区二区三区精品| 国产精品免费AⅤ片在线观看| 国产精品亚洲二区在线播放| 欧美 亚洲 另类 丝袜 自拍 动漫| 久久综合亚洲鲁鲁九月天| 信宜市| 无码AV中文字幕久久专区| 国产鲁鲁视频在线观看| 桓台县| 色成人亚洲| 亚洲夂夂婷婷色拍WW47| 国产一区二区三区导航| 久久精品国产99精品亚洲| 国产果冻豆传媒麻婆| 无码专区 人妻系列 在线|