分享

MVC Model Binder

 昵称10504424 2013-11-13

这篇博客是借助一个自己写的工程来理解model binder的过程.


MVC通过路由系统,根据url找到对应的Action,然后再执行action,在执行action的时候,根据action的参数和数据来源比对,生成各个参数的值,这就是model binder.

IActionInvoker


MVC中这个核心处理逻辑都在ControllerActionInvoker里,用reflector看,能看能到这个类继承了IActionInvoker接口

所以咱们可以根据代码模拟写出自己的CustomActionInvoker

以下是我自己写的ActionInvoker类

复制代码
 1     public class CustomActionInvoker : IActionInvoker
 2     {
 3 
 4         public bool InvokeAction(ControllerContext controllerContext, string actionName)
 5         {
 6             bool flag = false;
 7             try
 8             {
 9                 //get controller type
10                 Type controllerType = controllerContext.Controller.GetType();
11                 //get controller descriptor
12                 ControllerDescriptor controllerDescriptor = 
new ReflectedControllerDescriptor(controllerType); 13 //get action descriptor 14 ActionDescriptor actionDescriptor =
controllerDescriptor.FindAction(controllerContext, actionName);
15 Dictionary<string, object> parameters =

new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); 16 //get parameter-value entity 17 foreach (ParameterDescriptor parameterDescriptor in actionDescriptor.GetParameters()) 18 { 19 Type parameterType = parameterDescriptor.ParameterType; 20 //get model binder 21 IModelBinder modelBinder = new CustomModelBinder(); 22 IValueProvider valueProvider = controllerContext.Controller.ValueProvider; 23 string str = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName; 24 ModelBindingContext bindingContext = new ModelBindingContext(); 25 bindingContext.FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null; 26 bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType); 27 bindingContext.ModelName = str; 28 bindingContext.ModelState = controllerContext.Controller.ViewData.ModelState; 29 bindingContext.ValueProvider = valueProvider; 30 parameters.Add(parameterDescriptor.ParameterName,
modelBinder.BindModel(controllerContext, bindingContext));
31 } 32 ActionResult result = (ActionResult)actionDescriptor.Execute(controllerContext, parameters); 33 result.ExecuteResult(controllerContext); 34 flag = true; 35 } 36 catch (Exception ex) 37 { 38 //log 39 } 40 return flag; 41 } 42 }
复制代码

以下详细解释下执行过程

*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

其中CustomModelBinder的代码如下

注:我只是实现了简单的基本类型

中间有最核心的方法

ValueProvider


MVC默认提供了几种ValueProvider,每种都有对应的ValueProviderFactory,每种ValueProvider都对应着自己的数据源

注册ActionInvoker


上述过程讲完之后,还缺一个怎么应用上自己写的ActionInvoker,在Controller里提供了虚方法CreateActionInvoker

到此,整个过程已讲完。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多