在Model绑定中,Model的数据来源有很多种,在MVC里面则定义了一套ValueProvider的组件来处理Model数据来源多样性的问题,ValueProvider整个结构类似于字典(Dictrionary)的键值结构,通过给定的Key来获取Value。在一整套的组件当中,有接口部分的,有实现接口的抽象ValueProvider及其子类,有ValueProvider的抽象工厂ValueProviderFactory以及其子类,有对所有ValueProviderFactory统一存放的集合等,类图如下,但蒋老师书上的类图好像有个地方标错了

接口部分

IValueProvider:声明GetValue方法和ContainsPrefix方法,前者根据key获得对应的Value,这个key有可能是带前缀的;后者是判断是否有给定前缀的key。

IEnumerableValueProvider:继承IValueProvider。针对目标类型为集合(Collection)的数据提供,生命了GetKeysFromPrefix方法,返回容器中具有指定前缀的Key,这个过程默认是需要验证的。

IUnvalidatedValueProvider:继承IValueProvider。声明了另外一个GetValue方法,这个方法不需要对数据作验证。

ValueProvider部分

ValueProviderResult:ValueProvider(凡是实现IValueProvider的类)的方法GetValue返回值的类型,其中AttemptedValue属性是Value的字符串形式表示;RawValue是Value的原始的值,这属性是Object类型;ConvertTo方法是按给定的Type类型转换,然后返回相应类型的对象,其一个重载方法是加上了CultrualInfo类型。

NameValueCollectionValueProvider:实现了IValueProvider,IEnumerableValueProvider和IUnValidatedValueProvider接口。在这个类中,key和value是以一种类似字典集合的形式存放,在这个集合中一个key可以有多个value,所以才说类似字典集合。Key和value都是string类型。


关于前缀,这里能用到前缀主要分两种场景

1是对于复杂类型的前缀,用完全限定名表示,例如书上的Contact类中的Address属性它是个Address类型,所以要表示Address类型中各个属性时,需要给各个属性多加一个“Address”前缀。

2对于绑定的同一类型多个Model时,为了区分不同实例的相同属性都会添加前缀,以作区分。前缀的形式有三种:1)以“对象名.”形式;2)以“[index].”形式;3)以”[对象名].“形式

在执行GetKeysFromPrefix时,方括号(”[“,”]“)和点(”.”)都有特殊含义,是占位符。


FormValueProvider:继承NameValueCollectionValueProvider,用于从提交的表单处提供数据。

QueryStringValueProvider:继承NameValueCollectionValueProvider,用于从URL(精确地说是QueryString)中提供数据。

DictionaryValueProvider<TValue>:实现了IEnumerableValueProvider和IValueProvider接口,里面key和value是真正的字典集合形式存放,key是string类型,value则是泛型。

RouteDataValueProvider:继承DictionaryValueProvider<object>,从路由参数中提供值。

HttpFileCollectionProvider:继承DictionaryValueProvider<HttpPostedFileBase[]>,Model中有HttpPostFileBase的数据提供者,通常有上传文件的Action会用到这个类,个人估计是每次发送请求就开辟一个key。

ChildActionValueProvider:继承DictionaryValueProvider<object>,处理子Action(子Action是在某个View中被调用生成某个部分的HTML,个人觉得是类似产生Partial View的Action)时提供值,与RouteDataValueProviderd都是以object为类型的value,同样从ControllerContext的Routedata提取值,Routedata的value(实际上是RouteValueDictionary类型)作为ChildActionValueProvider的数据容器字典,ChildActionValueProvider与RouteDataValueProvider的区别在于GetValue方法,RouteDataValueProvider是根据RouteValueDictionary的键值对去匹配,而ChildActionValueProvider是从它本身的字典集中,已一个GUID值作为key对应的value里面去取值,这个GUID是ChildActionValueProvider的一个静态属性,以这个key获取的value,本身是一个字典集,这个字典集的每一对key/value都存在于ChildActionValueProvider本身的键值对容器中,相当于以GUID为key的value作为了一个副本。至于为什么要这样做,本人也不太明白。

ValueProviderCollection:实现了IValueProvider,IEnumerableValueProvider和IUnValidatedValueProvider接口。是IValueProvider的一个集合,里面实现各个接口的方法,都是遍历调用集合里面各个元素的方法,具体的可以参照书上。

工厂部分

ValueProviderFactory:是一个抽象类,根据ControllerContext来创建各种ValueProvider。而具体的创建工作则由其子类去实现,这里就使用了工厂方法模式。

ValueProviderFactoryCollection:ValueProviderFactory的集合,定义了GetValueProvider方法,传入ControllerContext后各个ValueProviderFactory的同名方法都会被执行,谁先创建了就返回那种类型的工厂,这里就涉及到优先级问题,实际上就是集合中各个元素的顺序问题。

ValueProviderFactories:使用了ValueProviderFactoryCollection,为这个Collection集合实际填入元素的就是这个ValueProviderFactories,那些工厂的顺序是ChildActionValueProviderFactory,FormValueProviderFactory,JsonValueProviderFactory,RouteDataValueProviderFactory,QueryStringValueProviderFactory,HttpFileCollectionValueProviderFactory。

  对于这个ValueProvider组件,从整体结构来说使用了工厂方法模式,工厂方法的优点那些不必说了,从使用背景来看,Model的来源各式各样,具体提供值的规则可不需要组件核心来负责,规则可以自由扩充,那相应创建规则对象的创建者也留不得组件核心来操作,对组件核心来说只需要给了足够的信息,各种场景可以使用自己的一套方式,来创建出Model的值,这里需要提供的充足的信息,ControllerContext包含了请求信息和路由信息。

ASP.NET MVC ValueProvider小结的更多相关文章

  1. ASP.NET MVC ModelValidator小结

    当用户通过UI输入数据向程序交互时,都会出现一个潜在的错误,数据错误,要检查用户提交的数据是否正确,需要做数据验证,在ASP.NET MVC中,每当Action执行前都会对传入Action的Model ...

  2. 学习“迷你ASP.NET MVC框架”后的小结

    看蒋老师MVC的书第二个大收获可以是算是看了这个迷你ASP.NET MVC框架了,虽然它远不如真正ASP.NET MVC(下文简称“MVC”)那么复杂庞大,但在迷你版中绕来绕去也够呛的.这部分我看了几 ...

  3. ASP.NET MVC 下拉列表使用小结

    ASP.NET MVC中下拉列表的用法很简单,也很方便,具体来说,主要是页面上支持两种Html帮助类的方法:DropDownList()和DropDownListFor().这篇博文主要作为个人的一个 ...

  4. ASP.NET MVC 5入门小结

    1.前言        本人在读研究僧一只,老师那里使用的是ASP.NET的Web Forms技术,真的要感慨一句:尼玛太老旧了!之前耳闻Python的高效开发,曾经学过一点Python的Django ...

  5. 白话ASP.NET MVC之二:Controller激活系统的概览

    前文简介:我们抽象类路由规则的对象,RouteBase是路由对象的抽象基类,ASP.NET 的路由系统中有唯一一个从RouteBase继承的路由对象,那就是Route类型了.我们注册了路由对象Rout ...

  6. ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)

    前面文章介绍了ASP.NET MVC中的模型绑定和验证功能,本着ASP.NET MVC没有魔法的精神,本章内容将从代码的角度对ASP.NET MVC如何完成模型的绑定和验证进行分析,已了解其原理. 本 ...

  7. ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)

    上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...

  8. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  9. 【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

随机推荐

  1. Oracle EBS - Form DEV Env

    1. 创建文件夹resource与forms, 以便存放pll与forms(主要用到APSTAND.fmb, APPSTAND.fmb, TEMPLATE.fmb)文件; 2. 修改注册表 HKEY_ ...

  2. 全屏滚动效果H5FullscreenPage.js

    前提: 介于现在很多活动都使用了 类似全屏滚动效果 尤其在微信里面 我自己开发了一个快速构建 此类项目的控件 与市面上大部分控件不同的是此控件还支持元素的动画效果 并提供多种元素效果 基于zepto. ...

  3. Codeforces Round #366 Div.2[11110]

    这次出的题貌似有点难啊,Div.1的Standing是这样的,可以看到这位全站排名前10的W4大神也只过了AB两道题. A:http://codeforces.com/contest/705/prob ...

  4. Linux crontab命令的使用方法

    crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读取和执行. 在 ...

  5. Android adt v22.6.2-1085508 自己主动创建 appcompat_v7 解决方法,最低版本号2.2也不会出现

    Android 开发工具升级到22.6.2在创建project时仅仅要选择的最低版本号低于4.0,就会自己主动生成一个项目appcompat_v7,没创建一个新的项目都会自己主动创建,非常是烦恼... ...

  6. ZOJ Monthly, March 2013

    A题 题目大意:给出一棵树,一开始节点值均为0,先要求完成在线操作:将某子树所有节点值取反,或者查询某子树总点权. 题解:很基础的线段树题,既然两个操作都是子树操作,那么就先树链剖分一下,将子树操作转 ...

  7. Xampp mysql无法启动的解决方案(转)

    如果出现mysql 无法启动表明在安装xampp 前已经安装了mysql,造成mysql服务无法启动. [mysql] MySQL Service detected with wrong path23 ...

  8. Justified Jungle

    Problem J: Justified Jungle Time limit: 6 s Memory l imit: 512 MiB As you probably know, a tree is a ...

  9. 在iOS中将string转成UTF-8编码

    在iOS开发中,特别是在对Web服务调用的时候,经常会遇到请求参数为中文的情况,那么这时候就需要将Url转成UTF-8编码才能进行请求.使用stringByAddingPercentEscapesUs ...

  10. 自己写的 读写 ini 配置文件类

    /// <summary> /// 不调用系统API 读写 ini 配置文件 /// </summary> public class RW_ini { #region ==== ...