在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. 【译】AS3利用CPU缓存

    利用CPU缓存   计算机有随机存取存储器RAM(译注:即我们常说的内存),但有更快形式的存储器.如果你希望你的应用程序的快速运行,你需要知道这些其他的存储器.今天的文章中讨论了它们,并给出了两个AS ...

  2. Unity3D音乐音效研究-MIDI与波表

    其实音乐音效这个命题本身没什么好研究的. Unity3D提供了丰富的结构和使用方式,足够使用了. 但是我有一些小小的想法和需求,一般的Unity资料并没有给我答案. 一个是容量要小.MP3.OGG的高 ...

  3. kafka的一些认识

    原创文章转载请注明出处:@协思, http://zeeman.cnblogs.com   近来无事研究了一下kafka,并且用golang连接kafka做了producer和consumer的简单测试 ...

  4. Hello Mybatis 04 使用spring-mybatis

    顺着上一篇,这里介绍下spring-mybatis的配置. 我们使用mybatis去操作数据库的时候,每次都要不停地openSession,closeSession好烦躁哇--这样工作哪里有效率可言! ...

  5. 七步,搭建基于Windows平台完美Jekyll博客环境

    最近,基于Jekyll新搭建了自己英文博客.整个过程搜索了不少资料,也尝试和过滤了不少工具和插件,最后的效果还是不错的.这里总结一下主要的七个步骤,感兴趣的朋友可以参考一下: 第一步,安装Ruby开发 ...

  6. make file教程(转)

    最近在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了以下这篇文章.通俗易懂.然后把它贴出 ...

  7. 基础才是重中之重~ConcurrentDictionary让你的多线程代码更优美

    回到目录 ConcurrentDictionary是.net4.0推出的一套线程安全集合里的其中一个,和它一起被发行的还有ConcurrentStack,ConcurrentQueue等类型,它们的单 ...

  8. Markdown快速入门

    现在博文写作次数渐渐变多,经常看到很多园友的博文样式都非常的美观,个人虽然是个土鳖,但对美也是有很强需求的,同时由于最近将要上线一个博客项目,因此也很关心如何可以更高效的编辑和发布博文.之前一直使用w ...

  9. hibernate(四)ID生成策略

    一.ID生成策略配置 1.ID生成方式在xml中配置方式: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping P ...

  10. poj 1950 Dessert(dfs枚举,模拟运算过程)

    /* 这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值! 如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值(这种方法见第二个代码),直到最后,这样不必每一次枚举都要从头再 ...