当前位置:编程学习 > asp >>

ASP.NET MVC以ValueProvider为核心的值提供系统: DictionaryValueProvider

NameValueCollectionValueProvider采用一个NameValueCollection作为数据源,DictionnaryValueProvider的数据源类型自然就是一个Dictionnary。NameValueCollection和Dictionnary都是一个键值对的集合,它们之间的不同之处在NameValueCollection运行元素具有相同的Key,Dictionnary却要求元素的Key具有唯一性。
目录
一、DictionaryValueProvider<TValue>
二、RouteDataValueProvider
三、HttpFileCollectionValueProvider
四、ChildActionValueProvider
五、实例演示:ChildActionValueProvider的值提供机制
六、ValueProviderCollection
一、DictionaryValueProvider<TValue>
DictionnaryValueProvider的类型全名为System.Web.Mvc.DictionaryValueProvider<TValue>,如下面的代码片断所示,DictionaryValueProvider<TValue>实现了IEnumerableValueProvider和IValueProvider接口,构造函数接受一个IDictionary<string, TValue>对象,该对象表示作为数据源的字典。定义在DictionaryValueProvider<TValue>中所有方法的逻辑与定义在NameValueCollectionValueProvider中的同名方法并没有本质区别。
   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
将当前路由数据作为数据源的RouteDataValueProvider继承自DictionaryValueProvider<TValue>。如下面的代码片断所示,基于当前Controller上下文构建的RouteDataValueProvider直接将表示当前路由数据的RouteData对象的Values属性(这是一个RouteValueDictionary对象)作为数据来源。
   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及其列表的参数来表示上传的文件,针对HttpPostedFileBase参数的Model绑定选用的数据就来源于表示当前请求的HttpRequestBase的Files属性,而具体参数值的提供最终通过具有如下定义的HttpFileCollectionValueProvider来实现。
   1: public sealed class HttpFileCollectionValueProvider : DictionaryValueProvider<HttpPostedFileBase[]>
   2: {   
   3:     public HttpFileCollectionValueProvider(ControllerContext controllerContext);
   4: }
如上面的代码所示,HttpFileCollectionValueProvider继承自DictionaryValueProvider<TValue>,泛型参数TValue的类型为HttpPostedFileBase数组,这是因为在同一个表单中可以定义多个同名的文件输入元素,所以在以文件元素名称作为Key的字典中,字典元素的值自然就是一个HttpPostedFileBase的列表。
为了让读者对HttpFileCollectionValueProvider采用的针对上传文件的值对象提供机制具有一个深刻的认识,我们来进行一个简单的实例演示。在通过Visual Studio的ASP.NET MVC项目模板创建的空Web应用中创建一个具有如下定义的HomeController。该Controller类型中定义了两个Action方法,默认的Index方法会将默认的View呈现出来,DisplayPostedFiles方法则通过创建的HttpFileCollectionValueProvider对象将上传文件的文件名称呈现出来。
   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方法中,我们针对当前Controller上下文创建HttpFileCollectionValueProvider对象,然后分别将字符“foo”和“bar”作为Key得到两个HttpPostedFileBase对象列表,并将它们的文件名打印出来。下面的代码表示Action方法Index对应的View。在一个针对Action方法DisplayPostedFiles的表单中我们定义了三个文件输入

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,