博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC以ValueProvider为核心的值提供系统: ValueProviderFactory
阅读量:5931 次
发布时间:2019-06-19

本文共 5321 字,大约阅读时间需要 17 分钟。

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

目录

一、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具有一个静态只读属性Factories返回一个表示ValueProviderFactory集合的ValueProviderFactoryCollection类型。

1: public static class ValueProviderFactories
2: {
3:     public static ValueProviderFactoryCollection Factories { get; }
4: }
5: 
6: public class ValueProviderFactoryCollection : Collection
7: {
8:     public ValueProviderFactoryCollection();
9:     public ValueProviderFactoryCollection(IList
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}
", "Connection", accept));
7:         Response.Write(string.Format("{0}: {1}
", "Accept-Charset", acceptCharset));
8:         Response.Write(string.Format("{0}: {1}
", "Accept Encoding", acceptEncoding));
9:         Response.Write(string.Format("{0}: {1}
", "Accept-Language", acceptLanguage));
10:         Response.Write(string.Format("{0}: {1}
", "Host", "host"));
11:         Response.Write(string.Format("{0}: {1}
", "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

作者:蒋金楠
微信公众账号:大内老A
微博:
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号
蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
你可能感兴趣的文章
MariaDB安装、Apache安装
查看>>
Linux CentOS 更新yum源
查看>>
命令帮助文档详解
查看>>
zabbix2.4版本升级到3.2版本
查看>>
gitlab+jenkins+maven+docker持续集成(九)——centos7 ansible安装及问题汇总
查看>>
ZT:从输入 URL 到页面加载完成的过程中都发生了什么事情?
查看>>
ssh多台服务器操作
查看>>
Github开源编辑器Atom
查看>>
Segment in recyclebin? Is it free?
查看>>
java 多态奇怪现象,子类还没有构造完成就开始干活了,谁来帮我解释?
查看>>
《Go语言编程》【2.7 完整示例】的错误
查看>>
操作系统基础
查看>>
Disk Space Checking
查看>>
Xampp 443端口被虚拟机占用问题
查看>>
JavaScript异常处理和事件处理
查看>>
DNS搭建
查看>>
QQ终于不再崩溃
查看>>
DELL R720 XEN安装 驱动问题
查看>>
DES 加密、解密
查看>>
ERP专业词汇
查看>>