MVC4 Action 方法的执行
1. ActionInvoker 的执行:
在MVC 中 包括Model绑定与验证在内的整个Action的执行是通过一个名为ActionInvoker的组件来完成的。 它同样具有 同步/异步两个版本。
分别实现了接口 IActionInvoker /IAsyncActionInvoker。
ASP.NET MVC 中真正用于Action方法同步和异步执行ActionInvoker 类型分别是 ContorllerActionInvoker /AsyncContollerActionInvoker.
AsyncContollerActionInvoker 是 ContorllerActionInvoker 的子类
也就是说 当Action 没有指定 实现 IActionInvoker /IAsyncActionInvoker 接口的时候 它默认是 执行AsyncContollerActionInvoker 的.
我们来看下面的代码片段:
我们通过 Ninject 对 SyncActionInvoker 和 AsyncActionInvoker 进行接口的映射,然后创建一个 ActionInvoker
其返回的结果分别是 各自的实例对象 AsyncContollerActionInvoker SyncActionInvoker AsyncActionInvoker (这中间有一个前提需要进行 缓冲的清除 )
public ActionResult Index()
{ return View(this.GetActionInvokers().ToArray());
} public IEnumerable<IActionInvoker> GetActionInvokers()
{
//Current 代表的是当前DependencyResolver。
NinjectDependencyResolver dependencyResolver = (NinjectDependencyResolver)DependencyResolver.Current;
//1. 默认创建的ActionInvoker
yield return this.CreateActionInvoker(); //2. 为Dependency注册针对IActionInvoker的类型映射
dependencyResolver.Register<IActionInvoker, SyncActionInvoker>();
yield return this.CreateActionInvoker(); //3. 为Dependency注册针对IAsyncActionInvoker的类型映射
dependencyResolver.Register<IAsyncActionInvoker, AsyncActionInvoker>();
yield return this.CreateActionInvoker();
}
注意: 创建 ActionInvoker 的3个步骤
1.) 在创建 CreateActionInvoker 的时候 如果返回 不为null 则将其默认为ActionInvoker, 也就是如上代码,(清除ActionInvoker缓存后) 它返回 AsyncContollerActionInvoker, 如果 返回null 则进入 下一步骤。
2.) 创建 IActionInvoker 规则同上
3.)创建 IAsyncActionInvoker 规则同上
2. ControllerDescriptor 的同步/异步
如果Controller使用ControllerActionInvoker ,它所有的Action总是以同步方式执行。
如果 Controller使用AsyncControllerActionInvoker 作为ActionInvoker时,却并不意味这总是异步方式。
通过两个描述对象 ControllerDescriptor 和 ActionDescriptor
在默认情况下 ReflectedControllerDescriptor 是通过ControllerActionInvoker 来创建的。
ReflectedAsyncControllerActionInvoker 是通过AsyncControllerActionInvoker 来创建的。
看如下代码 他们返回 返回的值 分别是对象类型的 ReflectedControllerDescriptor 和 ReflectedAsyncControllerActionInvoker 。
public class SyncActionInvoker : ControllerActionInvoker
{
public new ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext)
{
return base.GetControllerDescriptor(controllerContext);
}
} public class AsyncActionInvoker : AsyncControllerActionInvoker
{
public new ControllerDescriptor GetControllerDescriptor(
ControllerContext controllerContext)
{
return base.GetControllerDescriptor(controllerContext);
}
}
3.ActionDescriptor的执行。
Action 方法可以采用同步和异步执行方式,异步Action对应的ActionDescriptor 直接或者间接继承自抽象类AsyncActionDescriptor,
AsyncActionDescriptor 又是抽象类ActionDescriptor的子类。
同步和异步的 Action 分别 调用 Execute 和 BeginExecute/EndExecute方法来完成
AsyncActionDescriptor 重写了Execute 会抛出异常,所以 AsyncActionDescriptor对象只能采用异步执行。
同步Action 通过ReflectedControllerDescriptor 对象描述。
异步Action 通过ReflectedAsyncControllerDescriptor 对象描述。
返回Task的异步Action 则通过TaskAsyncControllerDescriptor 对象描述。
MVC4 Action 方法的执行的更多相关文章
- Asp.net mvc 中Action 方法的执行(三)
[toc] 前面介绍了 Action 方法执行过程中的一些主要的组件以及方法执行过程中需要的参数的源数据的提供以及参数的绑定,那些都可以看作是 Action 方法执行前的一些必要的准备工作,接下来便将 ...
- Asp.net mvc 中Action 方法的执行(一)
[toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...
- Asp.net mvc 中Action 方法的执行(二)
[toc] 前面介绍了 Action 执行过程中的几个基本的组件,这里介绍 Action 方法的参数绑定. 数据来源 为 Action 方法提供参数绑定的原始数据来源于当前的 Http 请求,可能包含 ...
- [yii2] 实现所有action方法之前执行一段代码或者方法
我做的是在执行任何方法之前,验证用户登陆状态! 其实就是在controller中写beforeaction()方法, 然后我的方案就是做一个基类,然后让你所有控制器继承你的基类, 如果控制器的基类用_ ...
- 如何让ASP.NET Web API的Action方法在希望的Culture下执行
在今天编辑推荐的<Hello Web API系列教程--Web API与国际化>一文中,作者通过自定义的HttpMessageHandler的方式根据请求的Accep-Language报头 ...
- MVC源码分析 - Action/Result 过滤器执行时机
前面 的篇章, 解析了Action方法的查找, 以及 Authorize, Action, Result, Error 过滤器的加载时机. 也花了两篇去看授权和错误过滤器的使用. 但是对于 Actio ...
- Web APi之控制器选择Action方法过程(九)
前言 前面我们叙述了关于控制器创建的详细过程,在前面完成了对控制器的激活之后,就是根据控制器信息来查找匹配的Action方法,这就是本节要讲的内容.当请求过来时首先经过宿主处理管道然后进入Web AP ...
- C# 给某个方法设定执行超时时间 C#如何控制方法的执行时间,超时则强制退出方法执行 C#函数运行超时则终止执行(任意参数类型及参数个数通用版)
我自己写的 /// <summary> /// 函数运行超时则终止执行(超时则返回true,否则返回false) /// </summary> /// <typepara ...
- 关于struts2中action请求会执行两次的问题
关于struts2中action请求会执行两次的问题 在struts2中发现,调用action中的方法,方法会被执行两次,后来发现调用的方法是get开头的,把它改为其他名称开头的后,就不会执行 ...
随机推荐
- 怎么分辨linux是红帽还是Centos系统
为什么需要分辨呢?因为centos是rhel的衍生版本,虎鼠傻傻你分不清楚!,你也可以使用yum,如果是rhel则报RHN disenable错!,还是用下面的专业些的command来搞吧! cat ...
- nrm操作
nrm操作 nrm use cnpm // 选择镜像nrm ls //查看镜像
- RHCE7 学习里程-1.配置IP,DNS
一.安装系统完成 1.系统安装完成之后不同于 6 的 ifconfig 命令.7 使用ip add ,这个跟网络设备配置端口IP 有点类似. 使用 ip add 查看网卡编号 cd /etc/s ...
- 系统架构设计方法论——TOGAF
https://blog.csdn.net/watermelonbig/article/details/77620847 1.ADM的架构开发阶段 ADM方法是由一组按照架构领域的架构开发顺序而排列成 ...
- Elasticsearch 搜索引擎
简介: Elasticsearch 是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据.它可以用于全文搜索,结构化搜索以及分析. 分布式实时文件存储,并将每一个字段都 ...
- cocos2d-js反射
如何在android平台上使用js直接调用Java方法 在cocos2d-js 3.0beta中加入了一个新特性,在android平台上我们可以通过反射直接在js中调用java的静态方法.它的使用方法 ...
- Python实现常见算法[3]——汉罗塔递归
#!/usr/bin/python # define three list var. z1 = [1,2,3,4,5,6,7,"1st zhu"] z2 = ["2st ...
- socket,TCP/IP的理解(转)
TCP/IP 要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间 ...
- ansible playbook模式及语法
一.什么是playbook及其组成 什么是playbook playbook 翻译过来就是"剧本" playbook的组成 play:定义的是主机的角色 task:定义的是具体执行 ...
- 清北学堂 day6 花
1.花( flower.cpp/c/pas)[ 问题描述]商店里出售 n 种不同品种的花.为了装饰桌面,你打算买 m 支花回家.你觉得放两支一样的花很难看,因此每种品种的花最多买 1 支.求总共有几种 ...