本章介绍了值提供器的作用,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类代码和自定义模型绑定器代码

 

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc; //IModelBinder
  6. namespace MvcApplication1.Sample_ModelBinder
  7. {
  8.     public class TestModelBinder : IModelBinder
  9.     {
  10.         public object BindModel(ControllerContext controllerContext,
  11.         ModelBindingContext bindingContext)
  12.         {
  13.             var valueProvider = bindingContext.ValueProvider;
  14.           
  15.                 int x = (int)valueProvider.GetValue("X").ConvertTo(typeof(int));
  16.                 int y = (int)valueProvider.GetValue("Y").ConvertTo(typeof(int));
  17.            
  18.            
  19.             return new Point(x, y);
  20.         }
  21.     }
  22.     public class PointModelBinder : IModelBinder
  23.     {
  24.         //public object BindModel(ControllerContext controllerContext,
  25.         //ModelBindingContext bindingContext)
  26.         //{
  27.         //    var valueProvider = bindingContext.ValueProvider;
  28.         //    int x = (int)valueProvider.GetValue("X").ConvertTo(typeof(int));
  29.         //    int y = (int)valueProvider.GetValue("Y").ConvertTo(typeof(int));
  30.         //    return new Point(x, y);
  31.         //}
  32.         private TModel Get<TModel>(ControllerContext controllerContext,ModelBindingContext bindingContext,string name)
  33.         {
  34.             string fullName = name;
  35.             //1.modelname
  36.             if (!String.IsNullOrWhiteSpace(bindingContext.ModelName))
  37.                 fullName = bindingContext.ModelName + "." + name;
  38.             //2.,valueProviderResult
  39.                 ValueProviderResult valueProviderResult =bindingContext.ValueProvider.GetValue(fullName);
  40.             //3.modelState
  41.                 ModelState modelState = new ModelState { Value = valueProviderResult };
  42.             //4.ModelstatebindingContext.ModelState
  43.                 bindingContext.ModelState.Add(fullName, modelState);
  44.             //5.null
  45.                 ModelMetadata metadata = bindingContext.PropertyMetadata[name];
  46.                 string attemptedValue = valueProviderResult.AttemptedValue;
  47.                 if (metadata.ConvertEmptyStringToNull&& String.IsNullOrWhiteSpace(attemptedValue))
  48.                     attemptedValue = null;
  49.             //6.  
  50.                 TModel model;
  51.                 bool invalidValue = false;
  52.                 try
  53.                 {
  54.                     model = (TModel)valueProviderResult.ConvertTo(typeof(TModel));
  55.                     metadata.Model = model;                  //XX
  56.                 }
  57.                 catch (Exception)
  58.                 {
  59.                     model = default(TModel);             //int 0.boolfalse,null
  60.                     metadata.Model = attemptedValue;
  61.                     invalidValue = true;              //null
  62.                 }
  63.             ///
  64.                 IEnumerable<ModelValidator> validators =
  65.                 ModelValidatorProviders.Providers.GetValidators(
  66.                 metadata,
  67.                 controllerContext
  68.                 );
  69.             
  70.                 foreach (var validator in validators)
  71.                     foreach (var validatorResult in
  72.                     validator.Validate(bindingContext.Model))
  73.                         modelState.Errors.Add(validatorResult.Message);
  74.                 if (invalidValue && modelState.Errors.Count == 0)
  75.                     modelState.Errors.Add(
  76.                     String.Format(
  77.                     "The value '{0}' is not a valid value forr {1}.",
  78.                     attemptedValue,
  79.                     metadata.GetDisplayName()
  80.                     )
  81.                     );
  82.                 return model;
  83.         }
  84.         public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  85.         {
  86.             //1.modelname object
  87.             //
  88.             if (!String.IsNullOrEmpty(bindingContext.ModelName) &&
  89.                 !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
  90.             {
  91.                 if (!bindingContext.FallbackToEmptyPrefix)
  92.                     return null;
  93.                 bindingContext = new ModelBindingContext
  94.                 {
  95.                     ModelMetadata = bindingContext.ModelMetadata,
  96.                     ModelState = bindingContext.ModelState,
  97.                     PropertyFilter = bindingContext.PropertyFilter,
  98.                     ValueProvider = bindingContext.ValueProvider
  99.                 };
  100.             }
  101.             bindingContext.ModelMetadata.Model = new Point();
  102.             return new Point(Get<int>(controllerContext, bindingContext, "X"), Get<int>(controllerContext, bindingContext, "Y"));
  103.         }
  104.     }
  105.     [ModelBinder(typeof(PointModelBinder))]
  106.     //[ModelBinder(typeof(TestModelBinder))]
  107.     public class Point
  108.     {
  109.         private int x;
  110.         public int X
  111.         {
  112.             get { return x; }
  113.           
  114.             set { x = value;}  //
  115.         }
  116.     
  117.         private int y;
  118.     public int Y
  119.     {
  120.         get { return y;}
  121.         set { y = value;}
  122.     }
  123.     
  124.         public Point(int x, int y)
  125.         {
  126.             this.x = x;
  127.             this.y = y;
  128.         }
  129.         public Point()
  130.         {
  131.         }
  132.     }
  133. }

 

 

通过调试可以发现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 模型绑定器的更多相关文章

  1. [MVC]自定义模型绑定器,从表单对模型进行赋值

    一.奇葩的问题 之前自己造轮子的时候,遇到一个很奇怪的问题,虽然需求很奇葩,但是还是尝试解决了一下 当提交的表单里包含多个重复名称的字段的时候,例如 <form action="/Te ...

  2. [转]ASP.NET MVC 4 (九) 模型绑定

    本文转自:http://www.cnblogs.com/duanshuiliu/p/3706701.html 模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C ...

  3. ASP.NET MVC 4 (九) 模型绑定

    模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...

  4. [转] ASP.NET MVC 模型绑定的功能和问题

    摘要:本文将与你深入探究 ASP.NET MVC 模型绑定子系统的核心部分,展示模型绑定框架的每一层并提供扩展模型绑定逻辑以满足应用程序需求的各种方法. 同时,你还会看到一些经常被忽视的模型绑定技术, ...

  5. ASP.NET MVC 模型绑定

    模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: ...

  6. MVC值提供组件ValueProvider的继承关系

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

  7. asp.net MVC 自定义模型绑定 从客户端中检测到有潜在危险的 Request.QueryString 值

    asp.net mvc 自定义模型绑定 有潜在的Requset.Form 自定义了一个模型绑定器.前端会传过来一些敏感字符.调用bindContext. valueProvider.GetValue( ...

  8. 第11课 std::bind和std::function(2)_std::bind绑定器

    1. 温故知新:std::bind1st和std::bind2nd (1)bind1st.bind2nd首先它们都是函数模板,用于将参数绑定到可调用对象(如函数.仿函数等)的第1个或第2个参数上. ( ...

  9. 关于QtCharts中的映射器与模型的使用

    简述 本文章基于博主在使用QtCharts中一些经验总结,相关了Qt类有QVXYModelMapper,CustomTableModel(一个继承了QAbstractTableModel的类,用于实现 ...

随机推荐

  1. django 表单系统 之 forms.ModelForm

    继承forms.ModelForm类实现django的表单系统 有时,我们在前端定义的<form>表单和后端定义的model结构基本上是一样的,那么我们可以直接在后端定义model后,定义 ...

  2. window下安装mysql详细步骤

    1.下载安装包 打开mysql官网下载页面:http://dev.mysql.com/downloads/mysql/ 1.选择相应的版本和平台 2.mysql配置 打开刚刚解压的文件夹F:\mysq ...

  3. PHP Laravel 本地化语言支持

        That`s it. 我发如今网上Laravel的学习资料实在是太少了.好多东西须要自己去弄.去理解. 我的方法另一个,就是去github上面下载老外写的Laravel站点,然后拿下来自己执行 ...

  4. 简明python教程五----数据结构

    python中有三种内建的数据结构:列表.元组和字典 list是处理一组有序项目的数据结构,即你可以在一个列表中存储一个序列的项目.在python中,每个项目之间用逗号分隔. 列表中的项目应该包括在方 ...

  5. PAT 1035 Password [字符串][简单]

    1035 Password (20 分) To prepare for PAT, the judge sometimes has to generate random passwords for th ...

  6. NUnit TestFixtureSetup 和 TestFixtureTearDown

    TestFixtureSetup 和 TestFixtureTearDown 在所有测试开始前(TestFixtureSetup)或结束后(TestFixtureTearDown)运行一 次.记住他只 ...

  7. Linux基础——硬盘分区、格式化及文件系统的管理

    1. 硬件设备与文件名的对应关系 掌握在Linux系统中,每个设备都被当初一个文件来对待. 设备 设备在Linux内的文件名 IDE硬盘 /dev/hd[a-d] SCSI硬盘 /dev/sd[a-p ...

  8. Django之查询总结

    models.Book.objects.filter(**kwargs): querySet [obj1,obj2]models.Book.objects.filter(**kwargs).value ...

  9. knockout 学习使用笔记------绑定值时赋值失败

    在使用knockout绑定值的时候,发现无论怎么赋值都赋值失败,最后检查前端页面才发现,同一个属性绑定值的时候,绑定了两次,而在js中进行属性绑定的时候是双向绑定的,SO,产生了交互影响.谨记之. 并 ...

  10. Uber中国在地方城市的人员架构是怎样的?

    http://www.thepaper.cn/newsDetail_forward_1390516 澎湃新闻:Uber中国在地方城市的人员架构是怎样的?   柳甄:一般是3人组成的小团队作战.一名城市 ...