ASP.NET MVC 4框架揭秘:Action的执行(1)[1]
Action的执行( )
作为Controller基类ControllerBase的Execute方法的核心在于对Action方法本身的执行和作为方法返回的ActionResult的执行 两者的执行是通过一个叫做ActionInvoker的组件来完成的
ActionInvoker
同样为ActionInvoker定义了一个接口IactionInvoker 如下面的代码片段所示 该接口定义了一个唯一的方法InvokeAction用于执行指定名称的Action方法 该方法的第一个参数是一个表示基于当前Controller上下文的ControllerContext对象
public interface IActionInvoker
{
void InvokeAction(ControllerContext controllerContext string actionName)
}
ControllerContext类型在真正的ASP NET MVC框架中要复杂一些 在这里我们对它进行了简化 仅仅将它表示成对当前Controller和请求上下文的封装 而这两个要素分别通过如下所示的Controller和RequestContext属性表示
public class ControllerContext
{
public ControllerBase Controller { get; set; }
public RequestContext RequestContext { get; set; }
}
ControllerBase中表示ActionInvoker的同名属性在构造函数中被初始化 在Execute方法中 通过作为方法参数的RequestContext对象创建ControllerContext对象 并通过包含在RequestContext中的RouteData得到目标Action的名称 然后将这两者作为参数调用ActionInvoker的InvokeAction方法
从前面给出的关于ControllerBase的定义中可以看到在构造函数中默认创建的ActionInvoker是一个类型为ControllerActionInvoker的对象 如下所示的代码片段反映了整个ControllerActionInvoker的定义 InvokeAction方法的目的在于实现针对Action方法的执行 由于Action方法具有相应的参数 在执行Action方法之前必须进行参数的绑定 ASP NET MVC将这个机制称为Model的绑定 而这又涉及另一个重要的组件ModelBinder
public class ControllerActionInvoker : IActionInvoker
{
public IModelBinder ModelBinder { get; private set; }
public ControllerActionInvoker()
{
this ModelBinder = new DefaultModelBinder()
}
public void InvokeAction(ControllerContext controllerContext
stringactionName)
{
MethodInfo method = controllerContext Controller GetType() GetMethods()
First(m =>string Compare(actionName m Name true) == )
List<object> parameters = new List<object>()
foreach (ParameterInfo parameter in method GetParameters())
{
parameters Add(this ModelBinder BindModel(controllerContext
parameter Name parameter ParameterType))
}
ActionResult actionResult = method Invoke(controllerContext Controller
parameters ToArray()) as ActionResult;
actionResult ExecuteResult(controllerContext)
}
}
ModelBinder
我们为ModelBinder提供了一个简单的定义 这与在真正的ASP NET MVC中的同名接口的定义不尽相同 如下面的代码片段所示 该接口具有唯一的BindModel方法 根据ControllerContext和Model名称(在这里实际上是参数名称)和类型得到一个作为参数的对象
public interface IModelBinder
{
object BindModel(ControllerContext controllerContext string modelName
Type modelType)
}
通过前面给出的关于ControllerActionInvoker的定义可以看到 在构造函数中默认创建的ModelBinder对象是一个DefaultModelBinder对象 由于仅仅是对ASP NET MVC的模拟 定义在自定义的DefaultModelBinder中的Model绑定逻辑比ASP NET MVC的DefaultModelBinder要简单得多 很多复杂的Model机制并未在我们自定义的DefaultModelBinder体现出来
lishixinzhi/Article/program/net/201311/16104