ASP.NET MVC ValueProvider小结

  在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包含了请求信息和路由信息。

时间: 2024-07-31 13:29:12

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

ASP.NET MVC ModelValidator小结

当用户通过UI输入数据向程序交互时,都会出现一个潜在的错误,数据错误,要检查用户提交的数据是否正确,需要做数据验证,在ASP.NET MVC中,每当Action执行前都会对传入Action的Model进行格式各样的验证,这些验证都是通过MVC中的验证组件ModelValidator来执行,不同的ModelValidator担当不同的验证任务,验证时会根据编码员的设置来使用不同的ModelValidator来执行,而不同的ModelValidator又由相应的ModelValidator来提供,下

ASP.NET MVC ViewData/ViewBag 简单小结

近期在项目中遇到一个问题,就是用ViewBag.Model存储匿名对象传递给View,但是需要根据条件给匿名对象添加属性,这个可真心不易,Google了一下发现很多方案都是动态编译神马的,感觉好高大上,最后也没采用,因为不知道动态编译的性能消耗大不大. 最后是自己简单研究了一下,在ViewBag.Model中存储了Dictionary<string, object>,在View通过Model[key]的方式可以正常读取相应的值,在此对ViewData和ViewBag的使用进行一个简单的小结:1

ASP.NET MVC升级到ASP.NET Core MVC踩坑小结

原文:ASP.NET MVC升级到ASP.NET Core MVC踩坑小结 写在前面 ASP.NET Core是微软新推出的支持跨平台.高性能.开源的开发框架,它的优势不必多说,因为已经说得太多了.当然,现在依然有着数量庞大的系统运行于.NET Framework上,由于有大量的Break Changes,很多项目项目团队也不敢贸然升级,其中的考量也不全部是技术原因,更多的可能还是业务推进因素. 小编自年前开始考虑升级一套电商系统,原先是基于.NET Framework 4.5的,打算直接升级到

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

前文简介:我们抽象类路由规则的对象,RouteBase是路由对象的抽象基类,ASP.NET 的路由系统中有唯一一个从RouteBase继承的路由对象,那就是Route类型了.我们注册了路由对象Route,UrlRoutingModule截获请求,把当前请求的Url地址和RouteTable路由表中注册的路由对象一个一个的比较,如果没有找到就返回Null,请求就到此终止了.如果有匹配的路由对象,选择第一个匹配的Route对象,并且根据该Route对象,生成了路由数据RouteData对象,本对象是

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

前面文章介绍了ASP.NET MVC中的模型绑定和验证功能,本着ASP.NET MVC没有魔法的精神,本章内容将从代码的角度对ASP.NET MVC如何完成模型的绑定和验证进行分析,已了解其原理. 本文的主要内容有: ● ModelBinder ● ValuePrivoder ● ModelMetadata ● 简单模型与复杂模型 ● 小结 ModelBinder ModelBinder是ASP. NET MVC用于模型绑定的核心组件,所有的ModelBinder都实现了IModelBinder

ASP.NET MVC XML绑定Action参数列表

昨天查看了 ASP.NET MVC 的生命周期,并没有找到类似的解决方案. 不过今天在 stackoverflow上找到了解决方案,没耐心的同学可以直接戳原文拷贝代码,原文地址:How to pass XML as POST to an ActionResult in ASP MVC .NET 看了外国同学的说明,才发现 MVC居然可以根据不同的请求 Content Type来选择 ValueProvider,这样提供了很好的扩展. MVC本身提供了 JsonValueProviderFacto

[转]Asp.Net MVC使用HtmlHelper渲染,并传递FormCollection参数的陷阱

http://www.cnblogs.com/errorif/archive/2012/02/13/2349902.html 在Asp.Net MVC 1.0编程中,我们经常遇见这样的场景,在新建一个对象时候,通过HtmlHelper的方式在View模型中渲染Html控件,当填写完相关内容后,通过Form把需要新建的内容Post回View对应Controller的Action(例如:Create),指定的Action可以通过接受FormCollection参数.值参数或者某个类的实例参数(比如:

asp.net webapi 使用小结

一星期前公司用webapi处理一些事情,自己总结一下用法. 1.创建一个空的webapi会默认有一下几个方法. public class ValueController : ApiController { // GET api/value public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/value/5 public st

Asp.net MVC 3 防止 Cross-Site Request Forgery (CSRF)原理及扩展

原理:http://blog.csdn.net/cpytiger/article/details/8781457 原文地址:http://www.cnblogs.com/wintersun/archive/2011/12/09/2282675.html Cross-Site Request Forgery (CSRF) 是我们Web站点中常见的安全隐患. 下面我们在Asp.net MVC3 来演示一下. 例如我们有一个HomeContoller中一个Submit Action,我们标记了Http