值提供器 AND 模型绑定器
本章介绍了值提供器的作用,ASP MVC自带的5中值提供器.以及模型绑定器的作用,自定义模型绑定器并使用自定义的模型绑定器(类型上加上[ModelBinder(typeof(xx))]或者在全局模型绑定器中注册)。
补充:全局模型绑定器中注册自定义模型绑定器
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.Add(typeof(Point), new PointModelBinder());
}
值提供器
ASP .NET MVC 框架自带的若干值提供器可以提供以下数据源中的数据:
● 子操作(RenderAction)的显式值
● 表单值
● 来自 XMLHttpRequest 的 JSON 数据
● 路由值
● 查询字符串值
● 上传的文件
值提供器来自值提供器工厂,并且系统按照值提供器的注册顺序来从中搜寻数据(上面
的列表使用的是默认顺序,自顶而下)。开发人员可以编写自己的值提供器工厂和值提供器,
并且还可以将它们插入到包含在 ValueProviderFactories.Factories 中的工厂列表中。当在模
型绑定期间需要使用额外的数据源时,开发人员通常选择编写自己的值提供器工厂和值提
供器。
除了 ASP .NET MVC 本身包含的值提供器工厂以外,开发团队也在 ASP.NET MVC 3
Futures 包中包含了一些提供器工厂和值提供器,可从 http://aspnet.codeplex.com/releases/view/
58781 上下载,或者安装 NuGet 包 Mvc3Futures。具体包括以下提供器:
● Cookie 值提供器
● 服务器变量值提供器
● Session 值提供器
● TempData 值提供器
模型绑定器
1.作用
模型扩展的另一部分是模型绑定器。它们从值提供器系统中获取值,并利用获取的值创建新模型或者填充已有的模型。
模型绑定器,从值提供器中获取值。
ASP .NET MVC 中的默认模型绑定器( 为方便起见,命名为DefaultModelBinder)是一段功能非常强大的代码,它可以对传统类、集合类、列表、数组 甚至字典进行模型绑定。
但是不支持对不改变对象的模型绑定(不可变指的是只能通过构造函数初始化值的类),如果遇见不可变的对象或者类型则默认的模型绑定器就无用了。此时需要自定义模型绑定器
2. 自定义模型绑定器
实现IModelBinder接口的 BinderModel方法
object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
主要是用到ModelBindingContext类
假设要对Point类进行模型绑定(Point类只能通过构造函数进行初始化,所以只能通过自定义模型提供器)
下面是Point类代码和自定义模型绑定器代码
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc; //IModelBinder
- namespace MvcApplication1.Sample_ModelBinder
- {
- public class TestModelBinder : IModelBinder
- {
- public object BindModel(ControllerContext controllerContext,
- ModelBindingContext bindingContext)
- {
- var valueProvider = bindingContext.ValueProvider;
- int x = (int)valueProvider.GetValue("X").ConvertTo(typeof(int));
- int y = (int)valueProvider.GetValue("Y").ConvertTo(typeof(int));
- return new Point(x, y);
- }
- }
- public class PointModelBinder : IModelBinder
- {
- //public object BindModel(ControllerContext controllerContext,
- //ModelBindingContext bindingContext)
- //{
- // var valueProvider = bindingContext.ValueProvider;
- // int x = (int)valueProvider.GetValue("X").ConvertTo(typeof(int));
- // int y = (int)valueProvider.GetValue("Y").ConvertTo(typeof(int));
- // return new Point(x, y);
- //}
- private TModel Get<TModel>(ControllerContext controllerContext,ModelBindingContext bindingContext,string name)
- {
- string fullName = name;
- //1.modelname
- if (!String.IsNullOrWhiteSpace(bindingContext.ModelName))
- fullName = bindingContext.ModelName + "." + name;
- //2.,valueProviderResult
- ValueProviderResult valueProviderResult =bindingContext.ValueProvider.GetValue(fullName);
- //3.modelState
- ModelState modelState = new ModelState { Value = valueProviderResult };
- //4.ModelstatebindingContext.ModelState
- bindingContext.ModelState.Add(fullName, modelState);
- //5.null
- ModelMetadata metadata = bindingContext.PropertyMetadata[name];
- string attemptedValue = valueProviderResult.AttemptedValue;
- if (metadata.ConvertEmptyStringToNull&& String.IsNullOrWhiteSpace(attemptedValue))
- attemptedValue = null;
- //6.
- TModel model;
- bool invalidValue = false;
- try
- {
- model = (TModel)valueProviderResult.ConvertTo(typeof(TModel));
- metadata.Model = model; //XX
- }
- catch (Exception)
- {
- model = default(TModel); //int 0.boolfalse,null
- metadata.Model = attemptedValue;
- invalidValue = true; //null
- }
- ///
- IEnumerable<ModelValidator> validators =
- ModelValidatorProviders.Providers.GetValidators(
- metadata,
- controllerContext
- );
- foreach (var validator in validators)
- foreach (var validatorResult in
- validator.Validate(bindingContext.Model))
- modelState.Errors.Add(validatorResult.Message);
- if (invalidValue && modelState.Errors.Count == 0)
- modelState.Errors.Add(
- String.Format(
- "The value '{0}' is not a valid value forr {1}.",
- attemptedValue,
- metadata.GetDisplayName()
- )
- );
- return model;
- }
- public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
- {
- //1.modelname object
- //
- if (!String.IsNullOrEmpty(bindingContext.ModelName) &&
- !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
- {
- if (!bindingContext.FallbackToEmptyPrefix)
- return null;
- bindingContext = new ModelBindingContext
- {
- ModelMetadata = bindingContext.ModelMetadata,
- ModelState = bindingContext.ModelState,
- PropertyFilter = bindingContext.PropertyFilter,
- ValueProvider = bindingContext.ValueProvider
- };
- }
- bindingContext.ModelMetadata.Model = new Point();
- return new Point(Get<int>(controllerContext, bindingContext, "X"), Get<int>(controllerContext, bindingContext, "Y"));
- }
- }
- [ModelBinder(typeof(PointModelBinder))]
- //[ModelBinder(typeof(TestModelBinder))]
- public class Point
- {
- private int x;
- public int X
- {
- get { return x; }
- set { x = value;} //
- }
- private int y;
- public int Y
- {
- get { return y;}
- set { y = value;}
- }
- public Point(int x, int y)
- {
- this.x = x;
- this.y = y;
- }
- public Point()
- {
- }
- }
- }
通过调试可以发现ModelBindingContext 包含了
1)值提供器(字符串值提供器,form值提供器,routeDate值提供其,httpfilCollection提供器,childAction值提供器)
2)model 指明了是 point类
3)属性元数据 propertyMetadata 表明了有 x,y两属性

模型绑定器的原理
注明:元数据指的是属性的详细信息,比如:dispalyname特性,属性类型 等等
1. 值提供器中检索值,然后在模型状态中记录值
1)ModelBindingContext的值提供器,默认提供了5种值提供器
2)在模型状态中记录值是因为如果信息错误,可以将错误信息回传显示
2.获得一个描述该属性的模型元数据的副本,然后再决定用户输入值的内容
3.将值转换为目标类型,转换错误则赋值类型的默认值
4.记录错误默认错误信息,回传model
5.使用自定义模型版定器,在类型上面加上
[ModelBinder(typeof(PointModelBinder))]
值提供器 AND 模型绑定器的更多相关文章
- [MVC]自定义模型绑定器,从表单对模型进行赋值
一.奇葩的问题 之前自己造轮子的时候,遇到一个很奇怪的问题,虽然需求很奇葩,但是还是尝试解决了一下 当提交的表单里包含多个重复名称的字段的时候,例如 <form action="/Te ...
- [转]ASP.NET MVC 4 (九) 模型绑定
本文转自:http://www.cnblogs.com/duanshuiliu/p/3706701.html 模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C ...
- ASP.NET MVC 4 (九) 模型绑定
模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...
- [转] ASP.NET MVC 模型绑定的功能和问题
摘要:本文将与你深入探究 ASP.NET MVC 模型绑定子系统的核心部分,展示模型绑定框架的每一层并提供扩展模型绑定逻辑以满足应用程序需求的各种方法. 同时,你还会看到一些经常被忽视的模型绑定技术, ...
- ASP.NET MVC 模型绑定
模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...
- MVC值提供组件ValueProvider的继承关系
MVC请求过程中中各组件调用顺序:值提供组件(IValueProvider)->模型绑定组件(IModelBinder)->模型验证组件 值提供组件接口 public interface ...
- asp.net MVC 自定义模型绑定 从客户端中检测到有潜在危险的 Request.QueryString 值
asp.net mvc 自定义模型绑定 有潜在的Requset.Form 自定义了一个模型绑定器.前端会传过来一些敏感字符.调用bindContext. valueProvider.GetValue( ...
- 第11课 std::bind和std::function(2)_std::bind绑定器
1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...
- 关于QtCharts中的映射器与模型的使用
简述 本文章基于博主在使用QtCharts中一些经验总结,相关了Qt类有QVXYModelMapper,CustomTableModel(一个继承了QAbstractTableModel的类,用于实现 ...
随机推荐
- 修改hosts文件不起作用
今天遇到个很奇怪的问题,在hosts文件里添加了一些域名指向后,发现根本没起作用,后来还发现个细节,就是hosts文件左下角有个小锁的标志,开始以为是杀毒软件之类的把他锁了.可是没找到在哪里有相关操作 ...
- 剑指Offer——二维数组中的查找
题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 分析: 因为二维数组 ...
- python基础之类的编码风格
自定义工作流程: 一开始应让代码结构尽可能简单.先尽可能在一个文件中完成所有的工作,确定一切都能正确运行后,再将类移动独立的模块中.如果你喜欢模块和文件的交互方式,可在项目开始时就尝试将类存储到模块中 ...
- java 集合类复习(未完结)
JAVA常用数据结构及原理分析(面试总结) https://blog.csdn.net/qq_29631809/article/details/72599708 java 中几种常用数据结构 ht ...
- 007-Centos 7.x 安装 Mysql 5.7.13
1. 下载mysql的repo源 CentOS 7.2的yum源中默认没有mysql,要先下载mysql的repo源 wget http://repo.mysql.com/mysql57-commun ...
- 006-虚拟机中centos7实现nat静态ip上网
1.设置虚拟机网卡VMnet8 2.修改虚拟机参数 (1).点击编辑-->虚拟网络编辑器,如下图设置 (2)nat设置如下[使用默认即可,记住网关.掩码等,非常重要,因为在centos里面要设置 ...
- 阿里云配置mysql远程连接
默认是不能用客户端远程连接的,阿里云提供的help.docx里面做了设置说明,mysql密码默认存放在/alidata/account.log 首先登录: mysql -u root -h local ...
- C语言-随机数
C语言使用rand()函数产生随机数, 使用rand()函数之前要先使用srand(time(0)), 以当前时间作为种子, 否则产生的随机数将不会变化. #include <stdio.h&g ...
- shiro配置
web.xml <!-- Shiro Filter is defined in the spring application context: --> <!-- 1. 配置 Shir ...
- springmvc 资源国际化
<!-- 关于国际化: 1. 在页面上能够根据浏览器语言设置的情况对文本(不是内容), 时间, 数值进行本地化处理 2. 可以在 bean 中获取国际化资源文件 Locale 对应的消息 3. ...