MVC请求过程中中各组件调用顺序:值提供组件(IValueProvider)-》模型绑定组件(IModelBinder)-》模型验证组件

值提供组件接口

public interface IEnumerableValueProvider : IValueProvider
{
IDictionary<string, string> GetKeysFromPrefix(string prefix);
} public interface IUnvalidatedValueProvider : IValueProvider
{
ValueProviderResult GetValue(string key, bool skipValidation);
}

ASP.NET MVC 包括值提供程序的实现,这些实现涵盖了大多数常见请求值源,例如查询字符串参数、表单字段和路由数据。

在运行时,ASP.NET MVC 使用 ValueProviderFactories(静态类,包含一个工厂集合) 类中注册的值提供程序计算模型绑定程序可以使用的请求值。

public static class ValueProviderFactories
{
public static ValueProviderFactoryCollection Factories { get; }
}

默认情况下,值提供程序集合按下面的顺序计算来自各种源的值:

  1. 以前绑定的操作参数(当该操作为子操作时)
  2. 表单字段 (Request.Form)
  3. JSON 请求主体中的属性值 (Request.InputStream),但仅当该请求为 AJAX 请求时
  4. 路由数据 (RouteData.Values)
  5. 查询字符串参数 (Request.QueryString)
  6. 已发布文件 (Request.Files)

值提供程序集合如同 Request 对象一样,实际上只不过是一个所谓的字典,即模型绑定程序可以使用且无需知道数据来源的键/值对的抽象层。 然而同 Request 字典相比,值提供程序框架进一步实现了这种抽象,它允许你完全控制模型绑定框架获取其数据的方式及位置。

MVC为每一个值提供器提供了一个工厂:ValueProviderFactory

下面的列表列出了定义在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对象。

次序(优先级)为:ChildActionValueProviderFactory、FormValueProviderFactory、JsonValueProviderFactory、RouteDataValueProviderFactory、QueryStringValueProviderFactory和HttpFileCollectionValueProviderFactory

值提供组件的继承关系

1,NameValueCollectionValueProvider类(public class NameValueCollectionValueProvider : IUnvalidatedValueProvider, IEnumerableValueProvider, IValueProvider)
NameValueCollectionValueProvider具有两个继承者,即FormValueProvider和QueryStringValueProvider

public sealed class FormValueProvider : NameValueCollectionValueProvider{}

public sealed class QueryStringValueProvider: NameValueCollectionValueProvider{}

2,DictionnaryValueProvider/DictionaryValueProvider<TValue>类(public class DictionaryValueProvider<TValue> : IEnumerableValueProvider, IValueProvider)

NameValueCollection和Dictionnary都是一个键值对的集合,它们之间的不同之处在NameValueCollection运行元素具有相同的Key,Dictionnary却要求元素的Key具有唯一性!

DictionaryValueProvider<TValue>具有三个继承者,RouteDataValueProvider、HttpFileCollectionValueProvider、ChildActionValueProvider

public sealed class RouteDataValueProvider : DictionaryValueProvider<object>{}

public sealed class HttpFileCollectionValueProvider : DictionaryValueProvider<HttpPostedFileBase[]>{}

public sealed class ChildActionValueProvider : DictionaryValueProvider<object>{}

3,ValueProviderCollection类

类型ValueProviderCollection不仅仅表示一个ValueProvider对象的集合,还作为一个单纯的ValueProvider来使用

public class ValueProviderCollection : Collection<IValueProvider>, IUnvalidatedValueProvider, IEnumerableValueProvider, IValueProvider{}

4,通过FormCollection类读取表单数据

//.net
public sealed class FormCollection : NameValueCollection,
IValueProvider{}
//使用方式,控制器内
public ActionResult FormCollection(FormCollection formCollection)
{
string name=formCollection["name"];
}
public ActionResult FormCollection(FormCollection formCollection)
{
if (ModelState.IsValid)
{
var user = new User();
//利用控制器的TryUpdateModel方法,进行转换
TryUpdateModel<User>(user, formCollection); }
}

FormCollection和Requert.Form都是NameValueCollection,他们之间有什么区别?

FormCllection是Request.Form的包装,其在内部实现了IModelBinder(private sealed class FormCollectionModelBinder),接口实现包装了(controllerContext.HttpContext.Request.Form和controllerContext.HttpContext.Request.Unvalidated.Form)

获取的值都是String类型,但是FormCllection是专门为MVC服务的。

1,Request类来自System.Web程序集,不方便测试,而且可移植性差,最新的.net core跨平台移除了对此程序集的依赖

2,Request.Form是只读集合,FormCollection则可以进行修改,

3,FormCollection实现了IValueProvider,可以利用MVC的机制,通过调用Controller.UpdateModel(TModel,FormCollection)进行手动模型更新。

参考:http://www.cnblogs.com/artech/archive/2012/05/17/value-provider-01.html

最新文章

  1. jquery tmpl 详解
  2. vim中执行shell命令
  3. java 基础加强--书籍+题目+上机测试
  4. CRM创建物料FM2
  5. [未完成][Mooc]关于Linxu的总结(一)
  6. java截取url中的值
  7. [Angular 2] Using the @Inject decorator
  8. cf466B Wonder Room
  9. avalonjs 1.3.7发布
  10. Ajax01 什么是ajax、获取ajax对象、ajax对象的属性和方法
  11. git常用使用命令
  12. Timer定时方法(间隔时间后执行)
  13. Vue生命周期,面试常见问题
  14. [Swift]LeetCode655. 输出二叉树 | Print Binary Tree
  15. Cheating sheet for vim
  16. 从零开始学 Web 之 移动Web(二)JD移动端网页,移动触屏事件
  17. [JZOJ5970] Space
  18. Yum安装Zabbix4.2.0
  19. hdu1542 Atlantis (线段树+矩阵面积并+离散化)
  20. rails中render 和 redirect_to的区别, each只能用在数组中,如果只有一个或者零个项,用each方法会报错undefined method `each&#39; for #...

热门文章

  1. 百度分享和bshare
  2. Shell脚本基础知识详细介绍(一)
  3. FPGA层次结构和复位策略
  4. Python if-elif-else
  5. Java标准I/O流介绍
  6. ThreadStart中带参数
  7. babel-polyfill使用简介
  8. python实现文件加密
  9. Python之select模块解析
  10. FFmpeg新版本(2016年10月份以后) 支持硬件解码