接着上一篇:MVC控制器的激活过程

一、代码现行,该伪代码大致解析了Action的执行的过程

try
{
Run each IAuthorizationFilter's OnAuthorization() method if(none of the IAuthorizationFilters cancelled execution)
{
Run each IActionFilter's OnActionExecuting() method
Run the action method
Run each IActionFilter's OnActionExecuted() method (in reverse order) Run each IResultFilter's OnResultExecuting() method
Run the action result
Run each IResultFilter's OnResultExecuted() method (in reverse order)
}
else
{
Run any action result set by the authorization filters
}
}
catch(exception not handled by any action or result filter)
{
Run each IExceptionFilter's OnException() method
Run any action result set by the exception filters
}

二、返回主战场Action执行方法中

public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
if (controllerContext == null)
{
throw new ArgumentNullException("controllerContext");
}
if (string.IsNullOrEmpty(actionName))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
}
       //描述了控制器的相关信息
ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(controllerContext);
//描述了相关Action的相关信息
ActionDescriptor actionDescriptor = this.FindAction(controllerContext, controllerDescriptor, actionName);
if (actionDescriptor != null)
{
//获取该action的所有Filter
FilterInfo filters = this.GetFilters(controllerContext, actionDescriptor);
try
{
AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor);
if (authorizationContext.Result != null)
{
this.InvokeActionResult(controllerContext, authorizationContext.Result);
}
else
{
if (controllerContext.Controller.ValidateRequest)
{
//地球人应该知道这个东西干嘛的,你知道吗?
ControllerActionInvoker.ValidateRequest(controllerContext);
}
IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor);
ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues);
this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result);
}
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception exception)
{
ExceptionContext exceptionContext = this.InvokeExceptionFilters(controllerContext, filters.ExceptionFilters, exception);
if (!exceptionContext.ExceptionHandled)
{
throw;
}
this.InvokeActionResult(controllerContext, exceptionContext.Result);
}
return true;
}
return false;
}
//上面的授权过程 
AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor);
if (authorizationContext.Result != null)
{
this.InvokeActionResult(controllerContext, authorizationContext.Result);
}
protected virtual AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor)
{
AuthorizationContext authorizationContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (IAuthorizationFilter current in filters)
{
current.OnAuthorization(authorizationContext);//很显然我们在自定义IAuthorizationFilter时,会去做事情在这里定义的。如果
  //此过程,authorizationContext的Result 被你给赋值了,那么所有的其他授权认证将会终止,系统将全力执行 this.InvokeActionResult(controllerContext, authorizationContext.Result);
if (authorizationContext.Result != null)
{
break;
}
}
return authorizationContext;
}

三、Action连同过滤器的执行,上面谈了授权过滤器的执行

IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, actionDescriptor);
ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, actionDescriptor, parameterValues);
this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result);
protected virtual IDictionary<string, object> GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
ParameterDescriptor[] parameters = actionDescriptor.GetParameters();
ParameterDescriptor[] array = parameters;
for (int i = ; i < array.Length; i++)
{
ParameterDescriptor parameterDescriptor = array[i];
dictionary[parameterDescriptor.ParameterName] = this.GetParameterValue(controllerContext, parameterDescriptor);
}
return dictionary;
}
protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
{
Type parameterType = parameterDescriptor.ParameterType;
IModelBinder modelBinder = this.GetModelBinder(parameterDescriptor);
IValueProvider valueProvider = controllerContext.Controller.ValueProvider;
string modelName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName;
Predicate<string> propertyFilter = ControllerActionInvoker.GetPropertyFilter(parameterDescriptor);
ModelBindingContext bindingContext = new ModelBindingContext
{
FallbackToEmptyPrefix = parameterDescriptor.BindingInfo.Prefix == null,
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType),
ModelName = modelName,
ModelState = controllerContext.Controller.ViewData.ModelState,
PropertyFilter = propertyFilter,
ValueProvider = valueProvider
};
object obj = modelBinder.BindModel(controllerContext, bindingContext);
return obj ?? parameterDescriptor.DefaultValue;
}
private IModelBinder GetModelBinder(ParameterDescriptor parameterDescriptor)
{
//action参数附带绑定信息了没?如果没有采用系统默认的方式进行绑定
return parameterDescriptor.BindingInfo.Binder ?? this.Binders.GetBinder(parameterDescriptor.ParameterType);
}
private IModelBinder GetBinder(Type modelType, IModelBinder fallbackBinder)
{
IModelBinder modelBinder = this._modelBinderProviders.GetBinder(modelType);
if (modelBinder != null)
{
return modelBinder;
}
if (this._innerDictionary.TryGetValue(modelType, out modelBinder))
{
return modelBinder;
}
modelBinder = ModelBinders.GetBinderFromAttributes(modelType, () => string.Format(CultureInfo.CurrentCulture, MvcResources.ModelBinderDictionary_MultipleAttributes, new object[]
{
modelType.FullName
}));
return modelBinder ?? fallbackBinder;
}
private static ModelBinderDictionary CreateDefaultBinderDictionary()
{
return new ModelBinderDictionary
{ {
typeof(HttpPostedFileBase),
new HttpPostedFileBaseModelBinder()
}, {
typeof(byte[]),
new ByteArrayModelBinder()
}, {
typeof(Binary),
new LinqBinaryModelBinder()
}, {
typeof(CancellationToken),
new CancellationTokenModelBinder()
}
};
}

下一篇: Action中的参数是怎么被赋值的

MVC中Action的执行过程的更多相关文章

  1. MVC中Action参数绑定的过程

    一.题外话 上一篇:MVC中Action的执行过程 ControllerContext 封装有了与指定的 RouteBase 和 ControllerBase 实例匹配的 HTTP 请求的信息. 二. ...

  2. 白话学习MVC(八)Action的执行二

    一.概述 上篇博文<白话学习MVC(七)Action的执行一>介绍了ASP.NET MVC中Action的执行的简要流程,并且对TempData的运行机制进行了详细的分析,本篇来分析上一篇 ...

  3. Asp.net mvc 中Action 方法的执行(一)

    [toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...

  4. Asp.net mvc 中Action 方法的执行(三)

    [toc] 前面介绍了 Action 方法执行过程中的一些主要的组件以及方法执行过程中需要的参数的源数据的提供以及参数的绑定,那些都可以看作是 Action 方法执行前的一些必要的准备工作,接下来便将 ...

  5. C# MVC 用户登录状态判断 【C#】list 去重(转载) js 日期格式转换(转载) C#日期转换(转载) Nullable<System.DateTime>日期格式转换 (转载) Asp.Net MVC中Action跳转(转载)

    C# MVC 用户登录状态判断   来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类Authenticati ...

  6. windows server 证书的颁发与IIS证书的使用 Dapper入门使用,代替你的DbSQLhelper Asp.Net MVC中Action跳转(转载)

    windows server 证书的颁发与IIS证书的使用   最近工作业务要是用服务器证书验证,在这里记录下一. 1.添加服务器角色 [证书服务] 2.一路下一步直到证书服务安装完成; 3.选择圈选 ...

  7. 转:Oracle中SQL语句执行过程中

    Oracle中SQL语句执行过程中,Oracle内部解析原理如下: 1.当一用户第一次提交一个SQL表达式时,Oracle会将这SQL进行Hard parse,这过程有点像程序编译,检查语法.表名.字 ...

  8. 游览器中javascript的执行过程

    在讲这个问题之前,先来补充几个知识点,如果对此已经比较了解可以直接跳过 大多数游览器的组件构成如图 在最底层的三个组件分别是网络,UI后端和js解释器.作用如下: (1)网络- 用来完成网络调用,例如 ...

  9. Asp.net mvc 中Action 方法的执行(二)

    [toc] 前面介绍了 Action 执行过程中的几个基本的组件,这里介绍 Action 方法的参数绑定. 数据来源 为 Action 方法提供参数绑定的原始数据来源于当前的 Http 请求,可能包含 ...

随机推荐

  1. 【Hello CC.NET】自动化发布时 Web.config 文件维护

    在 <[Hello CC.NET]CC.NET 实现自动化集成> 的 HellowWorld 中经实现: 1.获取源码 2.编译项目 3.集成测试 4.Ftp发布项目 5.创建安装包 6. ...

  2. 分享一个异步任务在遇到IO异常时支持递归回调的辅助方法

    public void TryAsyncActionRecursively<TAsyncResult>( string asyncActionName, Func<Task<T ...

  3. dojo/dom-style样式操作学习笔记

    基础总结 一个元素的样式信息由三个来源根据层叠规则确定.三个来源分别是: 由DOM元素style特性设置的内联样式 由style元素中嵌入的样式规则 由link元素引入的外部样式表 元素的样式 任何支 ...

  4. 本地DNS安装

    在centOS里最常用的DNS服务工具应该是bind了.下面就以bind为例做一个DNS服务. 首先查看bind 是否已经安装 Rpm -qa | gerp bind 如果没有的话就用yum 安装一下 ...

  5. jmx : ClientCommunicatorAdmin Checker-run

    今天遇到一个问题: 执行bat,关闭jmx的时候,由于程序关闭之后又去连接了一次,cmd窗口报错,类似: 2013-7-11 15:58:05 ClientCommunicatorAdmin rest ...

  6. IBatisNet:让insert操作返回新增记录的主键值

    项目引用ibatis包: IBatisNet.Common.dll --文件版本1.6.2.0 IBatisNet.DataAccess.dll IBatisNet.DataMapper.dll 项目 ...

  7. MVVM架构~Knockoutjs系列之对象与对象组合

    返回目录 在面向对象的程序设计里,对象是核心,一切皆为对象,对象与对象之间的关系可以表现为继承和组合,而在Knockoutjs或者JS里,也存在着对象的概念,今天主要说一下JS里的对象及对象的组合. ...

  8. 知方可补不足~SQL2005使用ROW_NUMBER() OVER()进行数据分页

    回到目录 数据分页是这个经常说的东西,无论在WEBForm还是WinForm中它都会被单独拿出来,或者是公用组件,或者是公用类库,反正对于数据分页这个东西,总是我们关注的一个话题,但事实上,数据分页归 ...

  9. Mybatis入门例子

    Mybatis是轻量级的持久化框架,的确上手非常快. Mybatis大体上的思路就是由一个总的config文件配置全局的信息,比如mysql连接信息等.然后再mapper中指定查询的sql,以及参数和 ...

  10. python 多线程网络编程 ( 二 )

    背景 我在[第一篇文章中]已经介绍了如何实现一个多线程的todo应用,接下来我将会研究如何使这个服务器完成下面这几个功能. 1.使用正则表达式解析用户发送的请求数据: 2.使用ThreadLocal技 ...