您的位置:首页 > 编程语言 > ASP

ASP.NET MVC5 ModelBinder

2016-10-19 15:38 281 查看

什么是ModelBinding

ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应。为了能够正确处理请求,Action的参数(如果有的话),必须在Action执行之前,根据相应的规则,把请求中所包含的数据提取出来并将映射为Action的参数值,这个过程就是ModelBinding。ModelBinding的作用就是为Action提供参数列表。

ModelBinding的好处

使代码变得更加简洁

帮助我们获取HTTP请求中的数据

帮助我们完成必要的数据类型转换

ASP.NET MVC中ModelBinding的实现过程

ASP.NET MVC中ModelBinding的实现过程比较复杂,这里简要说明它的总体流程。具体的实现过程可以看蒋金楠的《ASP.NET MVC5框架揭秘》或者看他的博客How ASP.NET MVC Works?,讲解很详细。



HTTP请求中的数据可能存在于querystring中,也可能在表单中,也有可能是JSON字符串。究竟从哪里获取数据,这要依赖于参数的描述信息
ParameterDescriptor


ParameterDescriptor
的获取需要借助于
ControllerDescriptor
ActionDescriptor
,它们分别用来描述Controller和Action

IModelBinderProvider
用于提供合适的ModelBinder对象,我们可以自己实现该接口以获取自定义的
IModelBinder


ModelBinding的核心
IModelBinder
,默认实现类是
DefaultModelBinder
,我们可以自己实现
IModelBinder
接口来扩展ModelBinder

IValueProvider
针对不同的数据源提供了数据的访问机制

ValueProviderResult
提供了两个ConvertTo方法重载以实现向指定目标类型的转换。

经过上述一系列的处理获取最终结果

自定义ModelBinder

自定义Modelbinder只需实现
System.Web.Mvc.IModelBinder
接口即可。这里需要注意一点,
System.Web.ModelBinding
命名空间下也有一个
IModelBinder
接口,不要搞错了。

public class LessonEditInfoViewModelBinder : IModelBinder
{
//根据前台传递的id值获取对象
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var idStr = controllerContext.HttpContext.Request["id"] ?? controllerContext.RouteData.Values["id"]?.ToString();
int id = 0;
if (!int.TryParse(idStr, out id))
{
return null;
}
var model = new LessonBLL().GetLessonEditInfo(id);
return model;
}
}


然后使用
ModelBinderAttribute
进行标注即可:

/*
根据前台传递的id值解析出对象数据,Action无需关注对象的获取,使代码变得清晰简洁
*/
public ActionResult Edit([ModelBinder(typeof(LessonEditInfoViewModelBinder))]LessonEditInfoViewModel lesson)
{
if (lesson == null)
{
//跨控制器的视图跳转要使用视图的路径+文件名
return View("/Views/Exception/GenericError.cshtml", new ExceptionViewModel { Title = "404", Description = "课程不存在!" });
}
return View(lesson);
}


如果项目中多处需要使用自定义的ModelBinder,那么再使用
ModelBinderAttribute
进行标注就不大合适了。这种情况我们可以使用自定义的ModelBinderProvier。代码如下:

public class CustomeModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (modelType == typeof(LessonEditInfoViewModel))
{
return new LessonEditInfoViewModelBinder();
}
return null;
}
}


然后将自定义的ModelBinderProvider注册到ASP.NET MVC系统中

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ModelBinderProviders.BinderProviders.Insert(0, new CustomeModelBinderProvider());
}
}


完成上述两步之后,就无需使用
ModelBuilderAttribute
进行标注了。

除此之外,还可在Global文件中使用使用
ModelBinder
类的
Binder
属性来注册ModelBinderProvider

ModelBinders.Binders.Add(typeof(LessonEditInfoViewModel),new LessonEditInfoViewModelBinder());


不同的ModelBinder提供策略有不同的优先级,具体如下:

在参数上使用CustomModelBinderAttribute

使用ModelBinderProviders.BinderProviers

使用ModelBinders.Binders

参数类型上标记CustomModelBinderAttribute

ASP.NET MVC中提供的DefaultModelBinder

注意,CustomModelBinderAttribute是抽象类,在ASP.NET MVC中有唯一子类ModelBinderAttribute。

参考文章:

Model Binders in ASP.NET MVC
ModelBinder——ASP.NET MVC Model绑定的核心
ASP.NET MVC以ValueProvider为核心的值提供系统
玩转Asp.net MVC 的八个扩展点
ASP.NET MVC中你必须知道的13个扩展点

版权声明

本文为作者原创,版权归作者雪飞鸿所有。
转载必须保留文章的完整性,且在页面明显位置处标明原文链接

如有问题, 请发送邮件和作者联系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: