模型绑定(Model Binding)是指用浏览器以HTTP请求方式发送的数据来创建.NET对象的过程。
动作方法的参数依赖于模型绑定过程(通过模型绑定器来实现)。利用整个HTTP请求所携带的数据(用户在表单中输入的数据、路由数据、请求URL中的查询字符串、请求中上传的文件)构造动作方法所需要参数对象的过程。
模型绑定过程(模型绑定器要做的事):
1.检测确认目标对象(要创建的对象,指动作方法的参数)的名称和类型;(动作方法参数的名称和类型)
2.通过对象名称查找数据源(请求),并找到可用数据(通常是字符串);(在请求数据中找到名称匹配的字符串数据)
3.根据对象类型将找到的数据值转换成目标类型;(将字符串类型数据转换成动作方法参数的类型)
4.通过对象名称、对象类型、和这种经过处理的数据来构造目标对象;(利用上述数据构造一个动作方法参数的对象)
5.将构造好的对象传送给动作调用器,并由动作调用器将对象注入到目标动作方法中去。(将目标对象传递给动作方法)
调用器:IActionInvoker
默认调用器:ControllerActionInvoker
模型绑定器:IModelBinder
默认模型绑定器:DefaultModelBinder
请求:Request
请求数据:Request.Form、Request.Files、RouteData.Values、Request.QueryString
模型:Model
模型属性:Model.Name
属性类型:String
控制器:Controller
动作方法:Action
动作参数:ActionParam
参数类型:string
参数值:"aa"
一、默认模型绑定器
DefaultModelBinder类查找参数数据的顺序(找到便停止)
数据源 | 描述 | 示例 |
Request.Form | 由用户在HTML的表单中提供(填写)的数据 | Request.Form["id"] |
RouteData.values | 用应用程序路由获得的值 | RouteData.Values["id"] |
Request.QueryString | 包含在请求URL中的查询字符串的部分数据 | Request.QueryString["id"] |
Request.Files | 请求中上传的文件 | Request.Files["id"] |
1.复合类型绑定:当动作方法的参数是复合类型时(不能用TypeConverter类进行转换的属性(简单类型:string、int....)),用反射来获取public属性集,然后依次绑定。
(1)易于绑定的HTML:
<div>@Html.LabelFor(m => m.HomeAddress.City) @Html.EditorFor(m => m.HomeAddress.City) </div>
<div><label for="HomeAddress_City">城市</label>
<input class="text-box single-line" id="HomeAddress_City" name="HomeAddress.City" type="text" value="" />
</div>
(2)指定自定义前缀:
绑定前缀为“HomeAddress”的数据
public ActionResult DisplaySummary([Bind(Prefix = "HomeAddress")]AddressSummary summary) { return View(summary); }
(3)有选择地绑定属性:
排除Country属性的绑定
public ActionResult DisplaySummary([Bind(Prefix = "HomeAddress",Exclude = "Country")]AddressSummary summary) { return View(summary); }
指定绑定的属性
绑定此类时,只绑定City属性,排除其他属性
[Bind(Include = "City")] public class AddressSummary { public string City { get; set; } public string Country { get; set; } }
二、手工调用模型绑定
1.UpdateModel(参数列表)方法:
public ActionResult Address(IList<AddressSummary> addresses) { addresses = addresses ?? new List<AddressSummary>(); UpdateModel(addresses,new FormValueProvider(ControllerContext)); //限制绑定源为表单内容 return View(addresses); }
值提供器:IValueProvider
内建IValueProvider实现
数据源 | IValueProvider实现 |
Request.Form | FormValueProvider |
RouteData.values | RouteDataValueProvider |
Request.QueryString | QueryStringValueProvider |
Request.Files | HttpFileCollectionValueProvider |
改进:最常用限制只查找表单值的方法:
public ActionResult Address(FormCollection formData) { IList<AddressSummary> addresses = new List<AddressSummary>(); UpdateModel(addresses, formData); return View(addresses); }
2.处理绑定错误
注:当自动调用模型绑定时,绑定错误不会发出异常信号。必须通过ModelState.IsValid属性来检查结果。
InvalidOperationException异常表示绑定错误
public ActionResult Address(FormCollection formData) { IList<AddressSummary> addresses = new List<AddressSummary>(); if (TryUpdateModel(addresses, formData)) { //todo:绑定正常 操作 } else { //todo:绑定异常 操作 } return View(addresses); }
三、定制模型绑定系统(IModelBinder)
1.自定义值提供器
ModelBindingContext类所定义的最有价值的属性
属性 | 描述 |
Model | 如果是手工调用绑定,可返回传递给UpdateModel方法的模型对象 |
ModelName | 返回被绑定模型的名称 |
ModelType | 返回被创建模型的类型 |
ValueProvider | 返回能用于从请求中获取数据值的IValueProvider实现 |
提示:ModelBinder注解属性和自定义模型绑定器来改变默认模型绑定器。