MVC中Action的执行过程
接着上一篇: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的执行过程的更多相关文章
- MVC中Action参数绑定的过程
一.题外话 上一篇:MVC中Action的执行过程 ControllerContext 封装有了与指定的 RouteBase 和 ControllerBase 实例匹配的 HTTP 请求的信息. 二. ...
- 白话学习MVC(八)Action的执行二
一.概述 上篇博文<白话学习MVC(七)Action的执行一>介绍了ASP.NET MVC中Action的执行的简要流程,并且对TempData的运行机制进行了详细的分析,本篇来分析上一篇 ...
- Asp.net mvc 中Action 方法的执行(一)
[toc] 在 Aps.net mvc 应用中对请求的处理最终都是转换为对某个 Controller 中的某个 Action 方法的调用,因此,要对一个请求进行处理,第一步,需要根据请求解析出对应的 ...
- Asp.net mvc 中Action 方法的执行(三)
[toc] 前面介绍了 Action 方法执行过程中的一些主要的组件以及方法执行过程中需要的参数的源数据的提供以及参数的绑定,那些都可以看作是 Action 方法执行前的一些必要的准备工作,接下来便将 ...
- 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 ...
- windows server 证书的颁发与IIS证书的使用 Dapper入门使用,代替你的DbSQLhelper Asp.Net MVC中Action跳转(转载)
windows server 证书的颁发与IIS证书的使用 最近工作业务要是用服务器证书验证,在这里记录下一. 1.添加服务器角色 [证书服务] 2.一路下一步直到证书服务安装完成; 3.选择圈选 ...
- 转:Oracle中SQL语句执行过程中
Oracle中SQL语句执行过程中,Oracle内部解析原理如下: 1.当一用户第一次提交一个SQL表达式时,Oracle会将这SQL进行Hard parse,这过程有点像程序编译,检查语法.表名.字 ...
- 游览器中javascript的执行过程
在讲这个问题之前,先来补充几个知识点,如果对此已经比较了解可以直接跳过 大多数游览器的组件构成如图 在最底层的三个组件分别是网络,UI后端和js解释器.作用如下: (1)网络- 用来完成网络调用,例如 ...
- Asp.net mvc 中Action 方法的执行(二)
[toc] 前面介绍了 Action 执行过程中的几个基本的组件,这里介绍 Action 方法的参数绑定. 数据来源 为 Action 方法提供参数绑定的原始数据来源于当前的 Http 请求,可能包含 ...
随机推荐
- windows 配置 apache + php
需要工具 apache 下载地址 php for windows (与apache同版本,使用线程安全)下载地址 vc (Visual Studio C++) 根据 apache 与 php 的版 ...
- DataTables 控件使用和心得 (1) - 入门
什么是DataTables DataTables是一个基于HTML/CSS/JavaScript的前端列表组件. 基于JQuery 开源并且免费(除特殊支持服务) 主要特色: 高性能,响应式,功能完整 ...
- 上网调查一下目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点?并在Github注册账户,写一篇博客记录注册的过程。
问题一:上网调查一下目前流行的源程序版本管理软件和项目管理软件都有哪些?各有什么优缺点?(以下内容为网上查询所得) Microsoft TFS(Team Foundation Server): 优点: ...
- 代码规范、代码复审、PSP
作业三: 代码规范.代码复审.PSP 代码规范 代码规范的重要性 一.规范的代码可以促进团队合作 一个项目大多都是由一个团队来完成,如果没有统一的代码规范,那么每个人的代码必定会风格迥异.且不说会存 ...
- Lucene系列-搜索
Lucene搜索的时候就要构造查询语句,本篇就介绍下各种Query.IndexSearcher是搜索主类,提供的常用查询接口有: TopDocs search(Query query, int n); ...
- win7-VS2010-IIS网站的发布问题
前提:IIS配置已经完成 问题描述:我们在机房实验里,大家的都可以访问同学A发布的IIS网站,但是,A却不能访问我们每个人的网站,而我们也不能互相访问(除了A). 问题解决:忙乎了半天,原来A同学的防 ...
- Java-练习方法之冒泡排序
1. 实现冒泡排序算法. int[] daxiao=new int[]{45,23,7,75,87,34,98,3,13}; for(int i=0;i<8;i++) { for(int j=i ...
- EF架构~引入规约(Specification)模式,让程序扩展性更强
回到目录 规约(Specification)模式:第一次看到这东西是在microsoft NLayer项目中,它是微软对DDD的解说,就像petshop告诉了我们MVC如何使用一样,这个规约模式最重要 ...
- 在Windows下安装Memcached
Windows下的Memcache安装: 需要运行命令行工具cmd 请以管理员权限运行 开始->附件->命令提示符,以管理员身份运行 假如当前C:\windows\system32,输入c ...
- Android开发学习之路-使用AsyncTask进行异步操作
通常情况下,我们要实现异步操作,也就是在子线程进行耗时操作比如下载或者加载图片等,然后在UI(主)线程中更新UI,使用的是Handler和Message来进行异步的实现,但是,谷歌官方在Android ...