MVC5 ModelBinder

什么是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框架揭秘》或者看他的博客How ASP.NET MVC Works?,讲解很详细。

 
  • 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进行标注了。

参考文章:

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

MVC5 ModelBinder的更多相关文章

  1. ASP.NET MVC5 ModelBinder

    什么是ModelBinding ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应.为了能够正确处理请求,Action的 ...

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

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

  3. 在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web ...

  4. MVC5知识点记录

    IIS/ASP.NET管道 原理永远是重中之重,所以在开篇的地方,先了解一下地址栏输入网址回车之后的故事. 不同IIS版本处理请求也不一样 IIS5 IIS 5.x 运行在进程InetInfo.exe ...

  5. [转]在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    本文转自:http://www.cnblogs.com/powertoolsteam/p/MVC5_GridView_2.html 背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5 ...

  6. 探索ASP.NET MVC5系列之~~~2.视图篇(上)---包含XSS防御和异步分部视图的处理

    其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...

  7. MVC5+EF6+MYSQl,使用codeFirst的数据迁移

    之前本人在用MVC4+EF5+MYSQL搭建自己的博客.地址:www.seesharply.com;遇到一个问题,就是采用ef的codefirst模式来编写程序,我们一般会在程序开发初期直接在glob ...

  8. MVC5 网站开发之九 网站设置

    网站配置一般用来保存网站的一些设置,写在配置文件中比写在数据库中要合适一下,因为配置文件本身带有缓存,随网站启动读入缓存中,速度更快,而保存在数据库中要单独为一条记录创建一个表,结构不够清晰,而且读写 ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

随机推荐

  1. WebAPI返回JSON的正确格式

    最近打算用WebAPI做服务端接口,返回JSON供ANDROID程序调用,结果试了好几次JSONObject都无法解析返回的JSON字符串.看了一下服务端代码: public string Get() ...

  2. 【大坑】DataGridView多线程更新修改Cell单元格卡死

    最新发现是Column的AutoSizeMode设置为AllCell调整宽度而造成的卡顿,还有就是在现在里面使用Invoke用匿名函数闭包的形式访问For循环的i变量值会不正确导致找不到索引而造成卡顿 ...

  3. mfc简易加法

    利用vs2013只做一个只有加法的计算器: 一.新建项目,然后如下图所示,进行选择,并创建. 二.下一步. 三.选择基于对话框,之后直接点完成 四.在整个编译器的最左边找到工具箱,并点击. /** 为 ...

  4. ORACLE 优化

    本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了 ORACLE数据库的优化调整方案. 关键词 ORACLE数据库 环境 ...

  5. BIO与NIO、AIO的区别

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO      在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Serve ...

  6. orale做报表常用函数和表达式的总结

    最近一段时间连续的做了几十张报表,通过原生sql对数据进行分析 ,也算是有了一定的了解,发现其中一些函数和表达式使用频率较高,现总结如下: (1).round()函数   round函数说白了就是把一 ...

  7. 【C语言】01-函数

    一.函数的分类 前面已经说过,C语言中的函数就是面向对象中的"方法",C语言的函数可以大概分为3类: 1.主函数,也就是main函数.每个程序中只能有一个.也必须有一个主函数.无论 ...

  8. T-SQL切割字符串方法小结

    T-SQL切割字符串方法小结,只有表值函数那个是自己的思想,其它都是来源于网络的思想,请大家不要笑话,嘻嘻~网上大牛太多,这点东西虽然上不了台面,但是也算是自己的一个学习吧,能够对一个人有用也行.再不 ...

  9. MySQL支持多种存储引擎

    MySQL的强大之处在于它的插件式存储引擎,我们可以基于表的特点使用不同的存储引擎,从而达到最好的性能. MySQL有多种存储引擎:MyISAM.InnoDB.MERGE.MEMORY(HEAP).B ...

  10. left join 改写标量子查询

    数据库环境:SQL SERVER 2005 有一博彩的赔率是1:20,它有2张业务表:smuchs(投注表),lottery(开奖表). smuchs表有3个字段,分别是sno(投注号码).smuch ...