值提供器 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的类,用于实现 ...
随机推荐
- 洛谷P4475 巧克力王国
洛谷P4475 巧克力王国 题目描述 巧克力王国里的巧克力都是由牛奶和可可做成的. 但是并不是每一块巧克力都受王国人民的欢迎,因为大家都不喜欢过于甜的巧克力. 对于每一块巧克力,我们设 x 和 y 为 ...
- 【零基础学习iOS开发】【02-C语言】08-基本运算
一.算术运算符 算术运算符很地简单.就是小学数学里面的一些加减乘除操作.只是呢.还是有一些语法细节须要注意的. 1.加法运算符 + 1 int a = 10; 2 3 int b = a + 5; 在 ...
- Java实现八大排序之冒泡排序
冒泡排序 冒泡排序的定义: 冒泡排序(Bubble Sort)它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该 ...
- Grunt JS构建环境搭建以及使用入门
Grunt JS构建环境搭建以及使用入门 1.应用场景 一种自动化任务处理工具,对于日常的需求(代码规则检查.代码合并)可以实现自动化执行,只需要保留package.json和Gruntfile.js ...
- 10046 trace详解(2)--tkprof
10046或10053生成的文件格式比较乱,直接查看有一定的困难,ORACLE自带的一个格式化命令工具tkprof可以将生成的.trc文件进行格式化,具体用说如下: 一.直接输入tkprof不带任 ...
- day4-迭代器、生成器yield
一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- 动态更改WebBrowser数据流内容
动态更改WebBrowser数据流内容 有时,由于软件的特殊需要,我们希望DELPHI在WebBrowser或embeddedwb里动态更改返回的数据内容,而这需要返回网页的所有原始源码, ...
- PAT 天梯赛 L1-014. 简单题 【水】
题目链接 https://www.patest.cn/contests/gplt/L1-014 AC代码 #include <iostream> #include <cstdio&g ...
- url末尾的斜杠作用探秘
今天突然好奇,想区分www.abc.com/efg 和www.abc.com/efg/这两个网址的区别.即分析一下url末尾加个斜杠是否有特殊的效果. 找到网上的介绍: 当Web服务器接收到对某个末尾 ...
- WPF MVVM TreeView 实现 右键选中 右键菜单
1.非MVVM模式:下载源代码WpfApplication1.zip <TreeView Height="200" PreviewMouseRightButtonDown=& ...