前言
本节主要来记录一下客户端发送请求的参数自动绑定为强类型的成员属性或方法参数也就是Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数。
IModelBinder
用于进行Model绑定的ModelBinder对象实现了接口IModelBinder。如下面的代码片断所示,IModelBinder接口具有唯一的BindModel方法用于实现针对某个参数的绑定操作,该方法的返回值表示的就是最终作为参数值的对象。用于进行Model绑定的ModelBinder对象实现了接口IModelBinder。如下面的代码片断所示,IModelBinder接口具有唯一的BindModel方法用于实现针对某个参数的绑定操作,该方法的返回值表示的就是最终作为参数值的对象。
// 摘要: // 定义模型联编程序所需的方法。 public interface IModelBinder { // 摘要: // 使用指定的控制器上下文和绑定上下文将模型绑定到一个值。 // // 参数: // controllerContext: // 控制器上下文。 // // bindingContext: // 绑定上下文。 // // 返回结果: // 绑定值。 object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext); }
IModelBinder的BindModel方法接受两个参数,一个是表示当前的Controller上下文,另一个是表示针对当前Model绑定的上下文,通过类型ModelBindingContext表示。在Controller初始化的时候,Controller上下文已经被创建出来,所以我们只要能够针对当前的Model绑定创建相应的ModelBindingContext,我们就能使用基于某个参数的ModelBinder得到对应的参数值。关于ModelBindingContext的创建我们会在后续部分进行的单独介绍,我们先来介绍一下ModelBinder的提供机制。
实现IModelBinder
新建UserInfoModelBinder类继承接口并实现IModelBinder
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { object obj = Activator.CreateInstance(bindingContext.ModelType); foreach (PropertyInfo p in bindingContext.ModelType.GetProperties()) { ValueProviderResult vpResult= bindingContext.ValueProvider.GetValue(p.Name); if (vpResult != null) { object value = vpResult.ConvertTo(p.PropertyType); p.SetValue(obj, value, null); } } return obj; }
这里有通过Activator.CreateInstance反射来定义一个对象。
通过在HomeController.cs中进行调用
public class HomeController : Controller { public ActionResult Test([ModelBinder(typeof(UserInfoModelBinder))]UserInfo userInfo) { return Content("Name:" + userInfo.Name + " Age:" + userInfo.Age); }
上面的bindingContext.ModelType其实就是Test的Action参数类型UserInfo。
接下来就是运行程序,通过MVC中的路由机制http://localhost:25943/Home/Test?Name=aehyok&age=25