知识大全 ASP.NET MVC: DictionaryValueProvider

Posted

篇首语:无志山压头,有志人搬山。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 ASP.NET MVC: DictionaryValueProvider相关的知识,希望对你有一定的参考价值。

ASP.NET MVC: DictionaryValueProvider  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  NameValueCollectionValueProvider采用一个NameValueCollection作为数据源 DictionnaryValueProvider的数据源类型自然就是一个Dictionnary NameValueCollection和Dictionnary都是一个键值对的集合 它们之间的不同之处在NameValueCollection运行元素具有相同的Key Dictionnary却要求元素的Key具有唯一性 一 DictionaryValueProvider<TValue>DictionnaryValueProvider的类型全名为System Web Mvc DictionaryValueProvider<TValue> 如下面的代码片断所示 DictionaryValueProvider<TValue>实现了IEnumerableValueProvider和IValueProvider接口 构造函数接受一个IDictionary<string TValue>对象 该对象表示作为数据源的字典 定义在DictionaryValueProvider<TValue>中所有方法的逻辑与定义在NameValueCollectionValueProvider中的同名方法并没有本质区别    : public class DictionaryValueProvider<TValue> : IEnumerableValueProvider IValueProvider   :    :     public DictionaryValueProvider(IDictionary<string TValue> dictionary CultureInfo culture);   :     public virtual bool ContainsPrefix(string prefix);   :     public virtual IDictionary<string string> GetKeysFromPrefix(string prefix);   :     public virtual ValueProviderResult GetValue(string key);   :

  二 RouteDataValueProvider将当前路由数据作为数据源的RouteDataValueProvider继承自DictionaryValueProvider<TValue> 如下面的代码片断所示 基于当前Controller上下文构建的RouteDataValueProvider直接将表示当前路由数据的RouteData对象的Values属性(这是一个RouteValueDictionary对象)作为数据来源    : public sealed class RouteDataValueProvider : DictionaryValueProvider<object>   :    :     public RouteDataValueProvider(ControllerContext controllerContext) :   :         base(controllerContext RouteData Values CultureInfo InvariantCulture)   :        :        :

  三 HttpFileCollectionValueProvider我们可以通过类型为file的输入元素进行文件的上传 在表示HTTP请求的HttpRequestBase对象中 上传文件通过只读属性Files表示 从下面的代码片断所示 该属性类型为HttpFileCollectionBase 是一个元素类型为HttpPostedFileBase的集合    : public abstract class HttpRequestBase   :      :     public virtual HttpFileCollectionBase Files get;    :    : public abstract class HttpFileCollectionBase : NameObjectCollectionBase ICollection IEnumerable   :      :     public virtual string[] AllKeys get;    :     public override int Count get;    :     public virtual HttpPostedFileBase this[int index] get;   :     public virtual HttpPostedFileBase this[string name] get;   :   : public abstract class HttpPostedFileBase  :   :     public virtual void SaveAs(string filename);  :   :     public virtual int ContentLength get;   :     public virtual string ContentType get;   :     public virtual string FileName get;   :     public virtual Stream InputStream get;   : 用于处理上传文件的Action方法通常定义类型为HttpPostedFileBase及其列表的参数来表示上传的文件 针对HttpPostedFileBase参数的Model绑定选用的数据就来源于表示当前请求的HttpRequestBase的Files属性 而具体参数值的提供最终通过具有如下定义的HttpFileCollectionValueProvider来实现    : public sealed class HttpFileCollectionValueProvider : DictionaryValueProvider<HttpPostedFileBase[]>   :       :     public HttpFileCollectionValueProvider(ControllerContext controllerContext);   :

如上面的代码所示 HttpFileCollectionValueProvider继承自DictionaryValueProvider<TValue> 泛型参数TValue的类型为HttpPostedFileBase数组 这是因为在同一个表单中可以定义多个同名的文件输入元素 所以在以文件元素名称作为Key的字典中 字典元素的值自然就是一个HttpPostedFileBase的列表 为了让读者对HttpFileCollectionValueProvider采用的针对上传文件的值对象提供机制具有一个深刻的认识 我们来进行一个简单的实例演示 在通过Visual Studio的ASP NET MVC项目模板创建的空Web应用中创建一个具有如下定义的HomeController 该Controller类型中定义了两个Action方法 默认的Index方法会将默认的View呈现出来 DisplayPostedFiles方法则通过创建的HttpFileCollectionValueProvider对象将上传文件的文件名称呈现出来    : public class HomeController : Controller   :    :     public ActionResult Index()   :        :         return View();   :        :     [HttpPost]   :     public void DisplayPostedFiles()   :       :         HttpFileCollectionValueProvider valueProvider = new HttpFileCollectionValueProvider(ControllerContext);  :         IEnumerable<HttpPostedFileBase> foo = (IEnumerable<HttpPostedFileBase>)valueProvider GetValue( foo ) ConvertTo(typeof(IEnumerable<HttpPostedFileBase>));  :         IEnumerable<HttpPostedFileBase> bar =  (IEnumerable<HttpPostedFileBase>)valueProvider GetValue( bar ) ConvertTo(typeof(IEnumerable<HttpPostedFileBase>));  :   :         Response Write( foo<br/> );  :         foreach (var file in foo)  :           :             Response Write(file FileName + <br/> );  :           :   :         Response Write( <br/>bar<br/> );  :         foreach (var file in bar)  :           :             Response Write(file FileName + <br/> );  :                      :       : 在DisplayPostedFiles方法中 我们针对当前Controller上下文创建HttpFileCollectionValueProvider对象 然后分别将字符 foo 和 bar 作为Key得到两个HttpPostedFileBase对象列表 并将它们的文件名打印出来 下面的代码表示Action方法Index对应的View 在一个针对Action方法DisplayPostedFiles的表单中我们定义了三个文件输入元素 其中前两个名称为 foo 和 bar    : @   :    using(Html BeginForm( DisplayPostedFiles Home    :        FormMethod Post new enctype= multipart/form data ))   :       :        <ul>   :         <li>File : <input type= file name= foo /></li>   :         <li>File : <input type= file   name= foo /></li>   :         <li>File : <input type= file   name= bar /></li>   :        </ul>   :        <input type= submit value= 提交 />        :       : 当我们运行该程序的时候 浏览器上会出现一个包含三个文件输入元素和提交按钮的页面 然后我们从本地选择任意三个文件(比如text txt text txt和text txt)并点击 提交 按钮 界面上会出现如下所示的输出结果    : foo   : text txt   : text txt   :    : bar   : text txt

  四 ChildActionValueProvider子Action和普通意义上的Action的不同之处在于它不能用于响应来自客户端的请求 而在某个View中被调用以生成某个部分的HTML View中针对某个子Action方法的调用通过如下所示的HtmlHelper的扩展方法Action来实现    : public static class ChildActionExtensions   :    :     //其他成员   :     public static MvcHtmlString Action(this HtmlHelper Helper string actionName);   :     public static MvcHtmlString Action(this HtmlHelper Helper string actionName object routeValues);   :     public static MvcHtmlString Action(this HtmlHelper Helper string actionName string controllerName);   :     public static MvcHtmlString Action(this HtmlHelper Helper string actionName RouteValueDictionary routeValues);   :     public static MvcHtmlString Action(this HtmlHelper Helper string actionName string controllerName object routeValues);   :     public static MvcHtmlString Action(this HtmlHelper Helper string actionName string controllerName RouteValueDictionary routeValues);   :

顾名思义 ChildActionValueProvider专门服务于针对子Action方法参数的Model绑定 如下面的代码片断所示 ChildActionValueProvider依然是DictionaryValueProvider<TValue>的继承者 不过这里的泛型参数类型Object 那么在作为数据源的字典中 具体的Key和Value究竟是怎样一个对象呢?   : public sealed class ChildActionValueProvider : DictionaryValueProvider<object>   :    :     public ChildActionValueProvider(ControllerContext controllerContext);   :     public override ValueProviderResult GetValue(string key);   : 当我们创建针对指定的Controller上下文创建一个ChildActionValueProvider对象时 会获取描述针对该上下文路由信息的RouteData对象 并将其Values属性表示的RouteValueDictionary对象作为其数据源 这可以从如下所示的ChildActionValueProvider的构造函数定义看出来    : public sealed class ChildActionValueProvider : DictionaryValueProvider<object>   :    :     //其他成员     :     public ChildActionValueProvider(ControllerContext controllerContext) :  base(controllerContext RouteData Values CultureInfo InvariantCulture)   :        :        : 但是ChildActionValueProvider的GetValue方法获取的值却并不是简单地来源于构造时针对当前上下文的路由信息 不然ChildActionValueProvider就和RouteDataValueProvider没有什么分别了 实际上 ChildActionValueProvider的GetValue方法获取的值来源于调用HtmHelper的扩展方法Action时通过参数routeValues指定的RouteValueDictionary 现在我们来简单介绍一下定义在ChildActionValueProvider的GetValue方法中的对象值的提供机制 如下面的代码片断所示 ChildActionValueProvider具有一个字符串类型的静态字段_childActionValuesKey 当该类型第一次被加载时 该字段被初始化成一个GUID    : public sealed class ChildActionValueProvider : DictionaryValueProvider<object>   :    :     //其他成员   :     private static string _childActionValuesKey = Guid NewGuid() ToString();   : 在某个View中通过HtmlHelper的扩展方法Action执行子Action方法时 如果通过参数routeValues指定的RouteValueDictionary不为空 会基于这个对象创建一个DictionaryValueProvider<TValue>对象 然后将这个对象添加到通过routeValues表示的原始的RouteValueDictionary对象中 对应的Key就是ChildActionValueProvider的静态属性_childActionValuesKey表示的GUID 这个RouteValueDictionary被进一步封装成表示请求上下文的RequestContext对象 目标子Action所在的Controller会在该请求上下文中被激活 而在Controller激活过程中表示Controller上下文的ControllerContext被创建出来 毫无疑问它包含了之前创建的RouteValueDictionary对象 而我们针对当前Controller上下文创建ChildActionValueProvider的时候指定的作为数据源的RouteValueDictionary对象就是这么一个对象    : @Html Action( XxxChildAction new Foo= Bar = Baz= )举个例子 假设我们在某个View中如果如下的方式调用当前Controller的子Action方法 XxxChildAction 并指定相应的路由数据(Foo Bar和Baz) 最终作为ChildActionValueProvider数据源的Dictionary<string object>对象结构如下图所示

  

 当调用ChildActionValueProvider的GetValue方法获取指定Key的值时 实际上并不会直接根据指定的Key去获取对应的值 而是根据通过其静态字段_childActionValuesKey值去获取对应的DictionaryValueProvider<object>对象 然后再调用该对象的GetValue根据指定的Key去获得相应的值

五 实例演示 ChildActionValueProvider的值提供机制为了印证上面介绍的关于ChildActionValueProvider的值提供机制 我们来演示一个简单的实例 在进行演示之前有一个点需要作一下简单说明 对于DictionaryValueProvider<TValue>对象来说 最终作为其数据源的通过私有字段_values表示的一个Dictionary<string ValueProviderResult对象 当我们调用GetValue方法是 只需要根据指定的Key从该字典对象中返回相应的ValueProviderResult即可    : public class DictionaryValueProvider<TValue> : IEnumerableValueProvider IValueProvider   :    :     //其他成员   :     private readonly Dictionary<string ValueProviderResult> _values;   : 在通过Visual Studio的ASP NET MVC 项目模板创建的空Web应用中定义如下一个默认的HomeController 默认的Action方法Index仅仅是将默认的View呈现出来而已 并没有特别之处 在另一个Action方法DisplayRouteData中 我们名称分别为Foo Bar和Baz的三个路由数据篡改成 abc ijk 和 zyz 然后根据当前Controller上下文创建一个ChildActionValueProvider对象 并通过反射的方式获取通过它的私有字段_values表示的Dictionary<string ValueProviderResult对象    : public class HomeController : Controller   :    :     public ActionResult Index()   :        :         return View();   :        :    :     public ActionResult DisplayRouteData()   :       :         ControllerContext RouteData Values[ Foo ] = abc ;  :         ControllerContext RouteData Values[ Bar ] = ijk ;  :         ControllerContext RouteData Values[ Baz ] = xyz ;  :   :         StringBuilder sb = new StringBuilder();  :         ChildActionValueProvider valueProvider = new ChildActionValueProvider(ControllerContext);  :         FieldInfo valuesField = typeof(DictionaryValueProvider<object>) GetField( _values BindingFlags Instance|BindingFlags NonPublic);  :         Dictionary<string ValueProviderResult> values = (Dictionary<string ValueProviderResult>)valuesField GetValue(valueProvider);  :         foreach (string key in values Keys)  :           :             sb Append(string Format( : <br/> key values[key] RawValue));  :             DictionaryValueProvider<object> innerValueProvider = values[key] RawValue as DictionaryValueProvider<object>;  :             if (innerValueProvider == null)  :               :                 continue;  :               :             sb Append(string Format( &nbsp;&nbsp;&nbsp;&nbsp; : <br/> Foo innerValueProvider GetValue( Foo ) RawValue));  :             sb Append(string Format( &nbsp;&nbsp;&nbsp;&nbsp; : <br/> Bar innerValueProvider GetValue( Bar ) RawValue));  :             sb Append(string Format( &nbsp;&nbsp;&nbsp;&nbsp; : <br/> Baz innerValueProvider GetValue( Baz ) RawValue));  :           :   :         sb Append( <br/>ChildActionValueProvider GetValue()<br/> );  :         sb Append(string Format( : <br/> Foo valueProvider GetValue( Foo ) RawValue));  :         sb Append(string Format( : <br/> Bar valueProvider GetValue( Bar ) RawValue));  :         sb Append(string Format( : <br/> Baz valueProvider GetValue( Baz ) RawValue));             :   :         return Content(sb ToString());  :       : 我们创建一个StringBuilder对象 并将用于输出获取到的Dictionary<string ValueProviderResult>对象的Key和Value的HTML添加其中 在进行遍历过程中 如果ValueProviderResult对象的RawValue属性是一个DictionaryValueProvider<object>对象 则调用其GetValue方法得到Key分别为Foo Bar和Baz的值 相应的输出的HTML一并添加到StringBuilder中 在程序的最后 我们直接调用ChildActionValueProvider的GetValue方法获取针对Foo Bar和Baz作为Key的值 并将输出Key和Value的HTML添加到StringBuilder中 最终针对生成的HTML字符串返回一个ContentResult对象 如下所示的代码反映Action方法Index对应的View的定义 在这里我们直接调用HtmlHelper的扩展方法Action执行定义在HomeController的Action方法DisplayRouteData 并指定了相应的路由数据(Foo Bar和Baz)    : @Html Action( DisplayRouteData new Foo = Bar = Baz = )运行我们的程序会在浏览器中得到如下的输出结果 我们可以从中看到针对于Controller和Action名称的路由数据和调用HtmlHelper扩展方法Action指定的数据数据均在作为ChildActionValueProvider数据源的字典对象中 除此之外 还具有一个DictionaryValueProvider<object>对象 对应的Key是一个GUID 这正是我们上面介绍的针对在HtmlHelper扩展方法Action中指定的路由数据创建的DictionaryValueProvider<object>对象 而调用GetValue方法获取到的值最终是通过它提供的    : Foo: abc   : Bar: ijk   : Baz: xyz   : controller: Home   : action: DisplayRouteData   : f dfba b abb b a :   :     System Web Mvc DictionaryValueProvider` [System Object]   :     Foo:    :     Bar:   :     Baz:   :   : ChildActionValueProvider GetValue()  : Foo:   : Bar:   : Baz: cha138/Article/program/net/201311/13871

相关参考

知识大全 ASP.NET 的MVC结构之AJAX

ASP.NET的MVC结构之AJAX  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ASPNET

知识大全 自己动手实现Asp.net的MVC框架

自己动手实现Asp.net的MVC框架  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  了解JAV

知识大全 ASP.NET上的另一个MVC实现

ASP.NET上的另一个MVC实现  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在ASPNET

知识大全 主攻ASP.NET.3.5.MVC架构之重生

主攻ASP.NET.3.5.MVC架构之重生  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs

知识大全 逃脱Asp.Net MVC框架

逃脱Asp.NetMVC框架  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 ASP.NET MVC开源了

ASP.NETMVC开源了  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  最新消息ASPNETM

知识大全 ASP.NET mvc学习笔记

ASP.NETmvc学习笔记  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  今天帮哥们解决几个问

知识大全 Asp.net MVC 中Ajax的使用

Asp.netMVC中Ajax的使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  MVC抛弃了

知识大全 在ASP.NET里 MVC框架添加AJAX支持

在ASP.NET里MVC框架添加AJAX支持  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!一引言&