Asp.net MVC的Model Binder工作流程以及扩展方法(1) - Custom Model Binder

简介:

在Asp.net MVC中, Model Binder是生命周期中的一个非常重要的部分。搞清楚Model Binder的流程,能够帮助理解Model Binder的背后发生了什么。同时该系列文章会列举MVC中Model Binder的扩展点,以及如何使用这些扩展点。

阅读目录:

一. MVC中的Model Binder的工作流程

二. 继承IModelBinder, 实现CustomeBinder

三. 使用Custom Model Binder的弊端

四. 总结

一, MVC中的Model Binder的工作流程

在MVC中, 当一个请求发送到服务器,先是要经过Route匹配, 找到对应的Controller和Action, 然后才是构建Action中的参数,也就是Model Binder的过程
这个可以从MVC的源码, ControllerActionInvoker中看出来。

blog-action-parameter-binder

在调用方法GetParameterValue获取参数的函数中, 会根据参数的描述信息,也就是ParameterDescriptor来获取对应的IModelBinder, 使用对应的IModelBinder来获取参数的值。在没有特殊为该参数指定ModelBinder的情况下, MVC使用默认的Model绑定类DefaultModelBinder.

所以我们扩展的第一处地方是,为参数绑定指定使用我们自定义的Model Binder, 自定义的Model Binder需要继承IModelBinder.

二, 继承IModelBinder, 实现CustomeBinder

2.1. MVC代码中的Session依赖问题

MVC的代码中,常常能够看到这样的代码:

复制代码
public ActionResult Index() 
{ 
          var user = Session["UserAccuont"] as UserAccount; //从Session中获取当前登录用户的信息 
          //send email 
          var email = user.Email; 
          return new EmptyResult(); 
}
复制代码

上面代码,需要从session中取得当前登录用户的信息。从session中取值导致了Index方法和Session耦合,也没办法进行单元测试。这个时候我们可以定义一个CustomeBinder来解决这个问题,解除Index方法对于Session的依赖。

2.2 自定义UserAccountModelBinder

我们定义的UserAccountModelBinder继承IModelBinder,实现了BindModel方法。该方法会从Session中取得UserAccount信息来构建Action方法中所需要的参数。

复制代码
public class UserAccountModelBinder : IModelBinder 
{ 
       public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
       { 
           if (controllerContext.HttpContext.Session["UserAccuont"] != null) 
           { 
               return controllerContext.HttpContext.Session["UserAccuont"]; 
           } 
           return null; 
       } 
}
复制代码

2.3 注册UserAccountModelBinder

在Global.asax.cs文件的Application_Start中, 注册UserAccountModelBinder。

复制代码
protected void Application_Start() 
{ 
           //注册UserAccountModelBinder, 指定UserAccount类型的参数,将会由UserAccountModelBinder来处理。

           ModelBinders.Binders.Add(typeof(UserAccount), new UserAccountModelBinder());

……….

}
复制代码

2.4 修改Index()方法

现在由于UserAccountModelBinder能够处理从Session中取UserAccount参数,所以我们的Index方法可以改造成这样:

复制代码
public ActionResult Index(UserAccount user) 
{ 
          //var user = Session["UserAccuont"] as UserAccount; //从Session中获取当前登录用户的信息 
          //send email 
          var email = user.Email; 
          return new EmptyResult(); 
}
复制代码

和最初代码不同之处是,我们的从session中取得user值的代码,不需要在Index方法中。而是由UserAccountModelBinder自动处理了。

2.5 背后的流程

现在来理一理,custome model binder的工作方法和流程。

request –> route解析 –> ControllerActionInvoker找ModelBinder处理参数 –> 根据参数类型寻找绑定的custome model binder, 也就是这里的UserAccountModelBinder –> UserAccountModelBinder 从Session中为Action的参数赋值。

三, 使用Custom Model Binder的弊端

上面的UserAccountModelBinder 的确解决了我们的Session依赖问题,但是这种以类型注册binder的方式,会带来潜在的风:

由于所有使用UserAccount为参数的Action方法,都会由UserAccountModelBinder来处理,也就是从session中取值。如果这个时候,我们的UserAccount的Create和Edit页面,提交UserAccount会发生什么? 是的,都会被UserAccountModelBinder处理,无法得到提交表单的值。

所以要慎用Custom Model Binder, 比较适合的例子是使用Custom Model Binder来绑定的参数,它的数据源只会来源于一处。上面的UserAccount在应用中,数据源就可能来自两处,Session和表单提交,所以是不适合Custom Model binder. 一个变通的办法是,再定义个类型SessionUserAccount.

四, 总结

使用Custom Model Binder能帮助我们解决一部分绑定问题,但是弊端是以类型绑定会导致应用的范围太广,带来意料不到的问题。

下一篇中,我们将使用CustomModelBinderAttribute来解决同样的问题,如果Custom Model Binder是全火力覆盖,那么CustomModelBinderAttribute就是定点清除。



本文转自JustRun博客园博客,原文链接:http://www.cnblogs.com/JustRun1983/p/3610509.html,如需转载请自行联系原作者


目录
相关文章
|
4月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
45 0
|
11天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
18 0
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0
|
2月前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
5 0
|
2月前
|
开发框架 搜索推荐 .NET
ASP.NET体检中心源码,实现检前、检中、检后全流程管理
健康体检系统遵循整个健康体检的实际流程,以提高工作效率、降低错检、防止漏检提高人性化服务水平为目的,在体检过程中可以高效、自动化、人性化的处理数据与提供服务。针对体检流程中工作强度在时间分配上不均匀等特点,解决了体检信息处理效率问题,在不增加体检中心人力资源投入或少投入的基础上,提升信息处理的效率,从而突破体检中心日处理体检人数的上限,为体检中心创造更大经济效益的同时,还能有效的降低体检工作者的劳动强度。
36 5
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
104 5
|
4月前
|
XML 前端开发 定位技术
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
27 0
|
4月前
|
前端开发
.net core mvc获取IP地址和IP所在地(其实是百度的)
.net core mvc获取IP地址和IP所在地(其实是百度的)
126 0