MVC Model Binder
这篇博客是借助一个自己写的工程来理解model binder的过程.
MVC通过路由系统,根据url找到对应的Action,然后再执行action,在执行action的时候,根据action的参数和数据来源比对,生成各个参数的值,这就是model binder.
IActionInvoker
MVC中这个核心处理逻辑都在ControllerActionInvoker里,用reflector看,能看能到这个类继承了IActionInvoker接口
public interface IActionInvoker
{
bool InvokeAction(ControllerContext controllerContext, string actionName);
}
所以咱们可以根据代码模拟写出自己的CustomActionInvoker
以下是我自己写的ActionInvoker类
public class CustomActionInvoker : IActionInvoker
{ public bool InvokeAction(ControllerContext controllerContext, string actionName)
{
bool flag = false;
try
{
//get controller type
Type controllerType = controllerContext.Controller.GetType();
//get controller descriptor
ControllerDescriptor controllerDescriptor =
new ReflectedControllerDescriptor(controllerType);
//get action descriptor
ActionDescriptor actionDescriptor =
controllerDescriptor.FindAction(controllerContext, actionName);
Dictionary<string, object> parameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
//get parameter-value entity
foreach (ParameterDescriptor parameterDescriptor in actionDescriptor.GetParameters())
{
Type parameterType = parameterDescriptor.ParameterType;
//get model binder
IModelBinder modelBinder = new CustomModelBinder();
IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
string str = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
ModelBindingContext bindingContext = new ModelBindingContext();
bindingContext.FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null;
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType);
bindingContext.ModelName = str;
bindingContext.ModelState = controllerContext.Controller.ViewData.ModelState;
bindingContext.ValueProvider = valueProvider;
parameters.Add(parameterDescriptor.ParameterName,
modelBinder.BindModel(controllerContext, bindingContext));
}
ActionResult result = (ActionResult)actionDescriptor.Execute(controllerContext, parameters);
result.ExecuteResult(controllerContext);
flag = true;
}
catch (Exception ex)
{
//log
}
return flag;
}
}
以下详细解释下执行过程
*Descriptor
执行过程中涉及到三个Descriptor,ControllerDescriptor,ActionDescriptor,ParameterDescriptor
ControllerDescriptor主要作用是根据action name获取到ActionDescriptor,代码中使用的是MVC自带的ReflectedControllerDescriptor,从名字就可以看出来,主要是靠反射获取到action.
ActionDescriptor,主要作用是获取parameterDescriptor,然后execute action.
parameterDescriptor,描述的是action的参数信息,包括name、type等
ModelBinder
最核心的方法. 将传递的数据和参数一一对应,笔者是自己写的CustomModelBinder,MVC默认用的是DefaultModelBinder 都实现了接口IModelBinder
public interface IModelBinder
{
object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);
}
其中CustomModelBinder的代码如下
public class CustomModelBinder : IModelBinder
{ public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
return this.GetModel(controllerContext, bindingContext.ModelType, bindingContext.ValueProvider, bindingContext.ModelName);
} public object GetModel(ControllerContext controllerContext, Type modelType, IValueProvider valueProvider, string key)
{
if (!valueProvider.ContainsPrefix(key))
{
return null;
}
return valueProvider.GetValue(key).ConvertTo(modelType);
}
}
注:我只是实现了简单的基本类型
中间有最核心的方法
valueProvider.GetValue(key).ConvertTo(modelType)
ValueProvider
MVC默认提供了几种ValueProvider,每种都有对应的ValueProviderFactory,每种ValueProvider都对应着自己的数据源
ValueProviderFactoryCollection factorys = new ValueProviderFactoryCollection();
factorys.Add(new ChildActionValueProviderFactory());
factorys.Add(new FormValueProviderFactory());
factorys.Add(new JsonValueProviderFactory());
factorys.Add(new RouteDataValueProviderFactory());
factorys.Add(new QueryStringValueProviderFactory());
factorys.Add(new HttpFileCollectionValueProviderFactory());
注册ActionInvoker
上述过程讲完之后,还缺一个怎么应用上自己写的ActionInvoker,在Controller里提供了虚方法CreateActionInvoker
protected override IActionInvoker CreateActionInvoker()
{
return new CustomActionInvoker();
}
到此,整个过程已讲完。
MVC Model Binder的更多相关文章
- MVC Model Binder 规则
http://www.cnblogs.com/mszhangxuefei/archive/2012/05/15/mvcnotes_30.html 使用默认的Model Binder(Using the ...
- Asp.net MVC的Model Binder工作流程以及扩展方法(2) - Binder Attribute
上篇文章中分析了Custom Binder的弊端: 由于Custom Binder是和具体的类型相关,比如指定类型A由我们的Custom Binder解析,那么导致系统运行中的所有Action的访问参 ...
- Asp.net MVC的Model Binder工作流程以及扩展方法(3) - DefaultModelBinder
Default Binder是MVC中的清道夫,把守着Model Binder中的最后一道防线.如果我们没有使用Custom Model Binder等特殊处理,那么Model的绑定都是有Defaul ...
- Asp.net MVC的Model Binder工作流程以及扩展方法(1) - Custom Model Binder
在Asp.net MVC中, Model Binder是生命周期中的一个非常重要的部分.搞清楚Model Binder的流程,能够帮助理解Model Binder的背后发生了什么.同时该系列文章会列举 ...
- ASP.NET MVC中默认Model Binder绑定Action参数为List、Dictionary等集合的实例
在实际的ASP.NET mvc项目开发中,有时会遇到一个参数是一个List.Dictionary等集合类型的情况,默认的情况ASP.NET MVC框架是怎么为我们绑定ASP.NET MVC的Actio ...
- Asp.net MVC的Model Binder工作流程以及扩展方法(1)
Asp.net MVC的Model Binder工作流程以及扩展方法(1)2014-03-19 08:02 by JustRun, 523 阅读, 4 评论, 收藏, 编辑 在Asp.net MVC中 ...
- ASP.NET MVC Model绑定(二)
ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...
- ModelBinder——ASP.NET MVC Model绑定的核心
ModelBinder——ASP.NET MVC Model绑定的核心 Model的绑定体现在从当前请求提取相应的数据绑定到目标Action方法的参数.通过前面的介绍我们知道Action方法的参数通过 ...
- ASP.NET MVC2之Model Binder
Model Binder在Asp.net MVC中非常简单.简单的说就是你控制器中的Action方法需要参数数据:而这些参数数据包含在HTTP请求中,包括表单上的Value和URL中的参 数等.而Mo ...
随机推荐
- 去除Linq to Sql 查询结果中的空格
原来的写法: Dim db = From city In DataContext1.AddressCity Where city.ProvinceID = dgvAddress(2, e.RowInd ...
- cloudstack 修改显示名称
http://192.168.153.245:8900/client/api?command=updateVirtualMachineid=922d15e1-9be0-44ac-9494-ce5afc ...
- jQuery 源码解析一:jQuery 类库整体架构设计解析
如果是做 web 的话,相信都要对 Dom 进行增删查改,那大家都或多或少接触到过 jQuery 类库,其最大特色就是强大的选择器,让开发者脱离原生 JS 一大堆 getElementById.get ...
- Oracle DataGuard搭建(二)
三.配置备库 创建catalog数据库 用dbca创建数据库,用oracle自带模板,不用em,启用归档,同一管理密码oracle,global name:dbcat1.node249.gewara, ...
- javascript 笔记(待续)
1.基础对象 var o=new Object(); o.xxx=1; o.xx=2; var 01={xxx=1,xx=2} 2.==与=== "5"==5 Tru ...
- Winform-控制边框显示属性
- Java模拟登陆【转载】
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- delphi 11 编辑模式 浏览模式
编辑模式 浏览模式 设置焦点 //在使用前需要Webbrowser已经浏览过一个网页 否则错误 uses MSHTML; ///获取Webbrowser编辑模式里面的内容procedure EditM ...
- 从user 登陆開始
首先.我们来看看我们的需求,看看需求里有没有你感兴趣的知识点: 用户登陆: 实现用户从网页登陆界面输入正确的username.password及验证码后跳转到一个页面显示登陆成功 要求: 1. 数据 ...
- android151 笔记 3
34. 对android虚拟机的理解,包括内存管理机制垃圾回收机制. 虚拟机很小,空间很小,谈谈移动设备的虚拟机的大小限制 16M , 谈谈加载图片的时候怎么处理大图片的,压缩. 垃圾回收,没有引用的 ...