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

在ASP.NET Model绑定系统中,用于提供数据值的ValueProvider对象通过ValueProviderFactory来创建。在ASP.NET MVC应用编程接口中,ValueProviderFactory继承自ValueProviderFactory类。本篇文章只要介绍基于ValueProviderFactory的ValueProvider的提供机制,以及如何通过自定义ValueProviderFactory实现我们需要的数据值的绑定方式。[本文已经同步到《How ASP.NET MVC Works?》中]

目录
一、ValueProviderFactory
二、ValueProviderFactory的注册
三、实例演示:创建一个自定义ValueProviderFactory

一、ValueProviderFactory

如下面的代码片断所示,ValueProviderFactory是一个抽象类,唯一的抽象方法GetValueProvider用于实现基于指定Controller上下文的ValueProvider创建。

   1: public abstract class ValueProviderFactory
   2: {
   3:     public abstract IValueProvider GetValueProvider(ControllerContext controllerContext);
   4: }

下面的列表列出了定义在Model绑定系统中的6个原生的ValueProviderFactory:

  • ChildActionValueProviderFactory:根据给定的Controller上下文创建一个ChildActionValueProvider对象。
  • FormValueProviderFactory:根据给定的Controller上下文创建一个FormValueProvider对象。
  • JsonValueProviderFactory:将以JSON形式表示的请求数据转换成一个Dictionary<string, object>对象,并最终创建一个DictionaryValueProvider<object>对象。
  • RouteDataValueProviderFactory:根据给定的Controller上下文创建一个RouteDataValueProvider对象。
  • QueryStringValueProviderFactory:根据给定的Controller上下文创建一个QueryStringValueProvider对象。
  • HttpFileCollectionValueProviderFactory:根据给定的Controller上下文创建一个HttpFileCollectionValueProvider对象。

二、ValueProviderFactory的注册

ValueProviderFactory在ASP.NET MVC应用中的注册通过静态类型ValueProviderFactories实现。如下面的代码片断所示,ValueProviderFactories具有一个静态只读属性Factories返回一个表示ValueProviderFactory集合的ValueProviderFactoryCollection类型。

   1: public static class ValueProviderFactories
   2: {
   3:     public static ValueProviderFactoryCollection Factories { get; }
   4: }
   5:  
   6: public class ValueProviderFactoryCollection : Collection<ValueProviderFactory>
   7: { 
   8:     public ValueProviderFactoryCollection();
   9:     public ValueProviderFactoryCollection(IList<ValueProviderFactory> list);    
  10:     public IValueProvider GetValueProvider(ControllerContext controllerContext);
  11: }

ValueProviderFactoryCollection的GetValueProvider方法返回的是一个ValueProviderCollection对象,集合中的每个ValueProvider通过对应的ValueProviderFactory来创建。ValueProviderFactory在ValueProviderFactoryCollection集合中的先后次序决定了创建的ValueProvider在ValueProviderCollection中的次序,而次序决定了使用优先级。

在默认的情况下ValueProviderFactories的Factories属性表示的ValueProviderFactoryCollection包含了上面我们介绍的6种ValueProviderFactory,次序(优先级)为:ChildActionValueProviderFactory、FormValueProviderFactory、JsonValueProviderFactory、RouteDataValueProviderFactory、QueryStringValueProviderFactory和。如果具有相同的名称的请求书去同时存在于请求表单和查询字符串中,前者会被选用。

以ValueProvider为核心的值提供系统中涉及到了三类组件/类型,即用于具体实现数据值提供的ValueProvider,ValueProvider通过ValueProviderFactotry,而ValueProviderFactotry通过ValueProviderFactotries进行注册。图5-4所示的UML体现了三者之间的关系。

三、实例演示:创建一个自定义ValueProviderFactory

ASP.NET MVC提供的6种ValueProviderFactory基本上已经可以满足我们绝大部分Model绑定需求,不过对于一些比较极端的场景,我们有可能需要自定义ValueProviderFactory。作为演示,我们创建一个以HTTP请求报头集合作为数据源的自定义ValueProviderFactory。

我们将自定义的ValueProviderFactory命名为HttpHeaderValueProviderFactory。如下面的代码片断所示,HttpHeaderValueProviderFactory的定义非常简单,在重写的GetValueProvider方法中,我们将针对指定的Controller上下文得到HTTP报头集合,并借此创建NameValueCollection对象。由于作为报头名称具有“-”字符,为了与参数命名规则相匹配,我们将该字符剔除。最终创建的实际上是一个NameValueCollectionValueProvider对象。

   1: public class HttpHeaderValueProviderFactory : ValueProviderFactory
   2: {   
   3:     public override IValueProvider GetValueProvider(ControllerContext controllerContext)
   4:     {
   5:         NameValueCollection requestData = new NameValueCollection();
   6:         var headers = controllerContext.RequestContext.HttpContext.Request.Headers;
   7:         foreach (string key in headers.Keys)
   8:         { 
   9:             requestData.Add(key.Replace("-",""),headers[key]);
  10:         }
  11:         return new NameValueCollectionValueProvider(requestData, CultureInfo.InvariantCulture);
  12:     }
  13: }

我们通过Visual Studio的ASP.NET
MVC项目模板创建一个空Web应用,并创建一个具有如下定义的HomeController。默认的Action方法Index具有一系列的参数,从参数名称我们可以看出它们代表一些常用的HTTP报头。我们最终将代表HTTP报头的参数值呈现出来。

   1: public class HomeController : Controller
   2: {       
   3:     public void Index(string connection, string accept, string  acceptCharset, string acceptEncoding ,string acceptLanguage, 
   4:         string host, string userAgent)
   5:     {
   6:         Response.Write(string.Format("{0}: {1}<br/>", "Connection", accept));
   7:         Response.Write(string.Format("{0}: {1}<br/>", "Accept-Charset", acceptCharset));
   8:         Response.Write(string.Format("{0}: {1}<br/>", "Accept Encoding", acceptEncoding));
   9:         Response.Write(string.Format("{0}: {1}<br/>", "Accept-Language", acceptLanguage));
  10:         Response.Write(string.Format("{0}: {1}<br/>", "Host", "host"));
  11:         Response.Write(string.Format("{0}: {1}<br/>", "User-Agent", userAgent));
  12:     }
  13: }

然后利用Global.asax中按照如下的方式利用静态类型对我们自定义的HttpHeaderValueProviderFactory进行注册。

   1: public class MvcApplication : System.Web.HttpApplication
   2: {  
   3:     //其他成员
   4:     protected void Application_Start()
   5:     {
   6:         //其他操作
   7:         ValueProviderFactories.Factories.Add(new HttpHeaderValueProviderFactory());
   8:     }
   9: }

当我们运行该程序的时候,会在浏览器中呈现如下的输出结果,而输出的结果正是当前请求的HTTP报头列表。

   1: Connection: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
   2: Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
   3: Accept Encoding: gzip,deflate,sdch
   4: Accept-Language: en-US,en;q=0.8
   5: Host: host
   6: User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19

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

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

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

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-10-31 04:49:57

ASP.NET MVC以ValueProvider为核心的值提供系统: ValueProviderFactory的相关文章

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

在进行Model绑定过程中,需要根据基于Action方法参数的绑定上下文从请求数据中提取相应的数据以提供相应的数据.具体来说,Model绑定的数据具有多个来源,可能来源于Post的表单或者JSON字符串,或者来源于当前的路由数据,也可能来源于请求地址的插叙字符串.ASP.NET MVC将这种基于不同数据来源的数据获取/提供机制实现在一个叫做ValueProvider的组件中.[本文已经同步到<How ASP.NET MVC Works?>中] 目录 一.IValueProvider与Value

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

NameValueCollectionValueProvider采用一个NameValueCollection作为数据源,DictionnaryValueProvider的数据源类型自然就是一个Dictionnary.NameValueCollection和Dictionnary都是一个键值对的集合,它们之间的不同之处在NameValueCollection运行元素具有相同的Key,Dictionnary却要求元素的Key具有唯一性.[本文已经同步到<How ASP.NET MVC Works?

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

ValueProviderFactory 在ASP.NET Model绑定系统中,用于提供数据值的ValueProvider对象通过ValueProviderFactory来创建.在ASP.NET MVC应用编程接口中,ValueProviderFactory继承自ValueProviderFactory类.本篇文章只要介绍基于ValueProviderFactory的ValueProvider的提供机制,以及如何通过自定义ValueProviderFactory实现我们需要的数据值的绑定方式.

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

NameValueCollectionValueProvider 在进行Model绑定过程中,需要根据基于Action方法参数的绑定上下文从请求数据中提取相应的数据以提供相应的数据.具体来说,Model绑定的数据具有多个来源,可能来源于Post的表单或者JSON字符串,或者来源于当前的路由数据,也可能来源于请求地址的插叙字符串.ASP.NET MVC将这种基于不同数据来源的数据获取/提供机制实现在一个叫做ValueProvider的组件中. 一.IValueProvider与ValueProvi

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

DictionaryValueProvider NameValueCollectionValueProvider采用一个NameValueCollection作为数据源,DictionnaryValueProvider的数据源类型自然就是一个Dictionnary.NameValueCollection和Dictionnary都是一个键值对的集合,它们之间的不同之处在NameValueCollection运行元素具有相同的Key,Dictionnary却要求元素的Key具有唯一性. 一.Dict

ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProvider

在<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator>中我们介绍了ASP.NET MVC用于Model验证的四种ModelValidator,那么这些ModelValidator是如何被创建的呢?ASP.NET MVC的很多组件(比如ModelBinder和Filter)都采用了基于Provider的提供机制,这篇文章为你讲述这些ModelValidator对应的ModelValidatorProvider. 一.ModelVali

ASP.NET MVC以ModelValidator为核心的Model验证体系:ModelValidatorProviders

前面篇文章我们分别介绍用真正用于实施Model验证的ModelValidator(<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator>),以及用于提供ModelValidator的ModelValidatorProvider(<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProvider>),那么对于ASP.NET MVC的Model验证体系来说,最终是通

ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator

旨在为目标Action方法的执行绑定输入参数的Model绑定过程伴随着对Model的验证.借助相应的验证特性,我们可以直接以声明的方式在Model类型上定义验证规则,这些规则将会作为Model元数据的一部分.具体在Model绑定过程中,ModelBinder通过ValueProvider为Model对象的某个属性提供相应属性值之后,会根据定义在基于该属性的Model元数据的验证规则实施验证.ASP.NET MVC的整个Model验证系统以组件ModelValidator为核心,或者说Model对

ModelBinder:ASP.NET MVC Model绑定的核心

Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数.通过前面的介绍我们知道Action方法的参数通过ParameterDescriptor来描述,ParameterDescriptor的BindingInfo属性表示的ParameterBindingInfo对象具有一个名为ModelBinder的组件用于完成针对当前参数的Model绑定.ModelBinder可以看成是整个Model绑定系统的核心,我们先来认识这个重要的组件. 一. ModelBinder 用于进行M