博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC5 ModelBinder
阅读量:4641 次
发布时间:2019-06-09

本文共 3074 字,大约阅读时间需要 10 分钟。

什么是ModelBinding

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

ModelBinding的好处

  1. 使代码变得更加简洁
  2. 帮助我们获取HTTP请求中的数据
  3. 帮助我们完成必要的数据类型转换

ASP.NET MVC中ModelBinding的实现过程

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

 
  • HTTP请求中的数据可能存在于querystring中,也可能在表单中,也有可能是JSON字符串。究竟从哪里获取数据,这要依赖于参数的描述信息ParameterDescriptor
  • ParameterDescriptor的获取需要借助于ControllerDescriptorActionDescriptor,它们分别用来描述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提供策略有不同的优先级,具体如下:

  1. 在参数上使用CustomModelBinderAttribute
  2. 使用ModelBinderProviders.BinderProviers
  3. 使用ModelBinders.Binders
  4. 参数类型上标记CustomModelBinderAttribute
  5. ASP.NET MVC中提供的DefaultModelBinder

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

参考文章:

版权声明

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

如有问题, 请和作者联系。

转载于:https://www.cnblogs.com/Cwj-XFH/p/5977508.html

你可能感兴趣的文章
[LintCode] 空格替换
查看>>
JSSDK微信支付封装的支付类方法,代码比较齐全,适合收藏
查看>>
Java线程及Jvm监控工具
查看>>
python基础学习1-列表推导式和字典推导式
查看>>
mfc Radio Buttons
查看>>
[JavaScript]父子窗口间参数传递
查看>>
86. Partition List
查看>>
[LintCode] 378 Convert Binary Search Tree to Doubly Linked List 解题报告
查看>>
JAVA-初步认识-常用对象API(集合框架-泛型-泛型限定-上限的体现)
查看>>
查找一个字段所处的数据库及表
查看>>
第一周学习进度+四则运算1.0版
查看>>
baba 运动网
查看>>
for循环小练习
查看>>
JAE京东云引擎Git上传管理代码教程和京东云数据库导入导出管理
查看>>
教你如何迅速秒杀掉:99%的海量数据处理面试题
查看>>
高血压吃什么好?
查看>>
Java for LeetCode 047 Permutations II
查看>>
React工作原理
查看>>
JS 获取当前时间
查看>>
bzoj3238 [Ahoi2013]差异
查看>>