ASPNET Core ActionFilterAttribute中断后续请求
转载自:https://www.cnblogs.com/luconsole/p/4346669.html
SPNET MVC如何正确的中断请求?
感觉是这样?
在aspnet开发过程中如果想要中断当前的http处理,以前在aspnet中一直是Response.End();
在这Response.End()之后的当前请求应有的代码都不会执行了,
但是在aspnetmvc中,就算调用Response.End();还是会执行!!
|
1
2
3
4
5
6
7
8
9
10
11
12
|
//aspnet webform if(ok) Response.End(); //save不会继续执行 Save(); //aspnet mvc if (ok) Response.End(); //save会继续执行 Save(); |
aspnetmvc action 如何简单处理?
如果你在action中的逻辑需要中断,你可以变通的通过逻辑判断来中断,
比如:

if(ok)
{
//应有的逻辑
}
else
{
//中断
} //或者 if(!ok)
return Content("NO");

但是如果是在过滤器中!
|
1
2
3
4
5
6
|
protected virtual void OnActionExecuted(ActionExecutedContext filterContext);protected virtual void OnActionExecuting(ActionExecutingContext filterContext);protected virtual void OnAuthorization(AuthorizationContext filterContext);protected virtual void OnException(ExceptionContext filterContext);protected virtual void OnResultExecuted(ResultExecutedContext filterContext);protected virtual void OnResultExecuting(ResultExecutingContext filterContext); |
你的 逻辑判断 和 Response.End(); 都是无效的!
看到很多人都是用的跳转!如果是aspnet mvc web api,往哪里跳转呢。
正确的aspnet mvc filter Cancel Execution姿势!
那就是赋值 filterContext.Result!
例如OnActionExecuting

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var headerAuth = filterContext.HttpContext.Request.Headers["_applogin_"];
if (string.IsNullOrEmpty(headerAuth))
{
filterContext.Result = new ContentResult()
{
Content = "{code:9999,message:'no login'}",
ContentEncoding = Encoding.UTF8
};
} base.OnActionExecuting(filterContext);
}
}

为什么赋值了Context.Result就不会继续执行后面的过滤器和action的代码?
先看下aspnetmvc源码!
aspnet mvc 源码:ControllerActionInvoker.cs
附上简单注释:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/// <summary>/// 执行一个 控制器方法/// </summary>/// <param name="controllerContext"></param>/// <param name="actionName"></param>/// <returns></returns>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); //action不为空 if (actionDescriptor != null) { //获取或滤器信息 FilterInfo filters = this.GetFilters(controllerContext, actionDescriptor); try { //获取aspnetmvc自带的Authorization信息 AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, actionDescriptor); //这里我们可以看到,在授权的代码里面也可以赋值,当在获取授权时赋值了Result,当前执行会被返回Result,action的代码和过滤器的代码将不会执行 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); //开始执行过滤器和action 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;}//执行过滤器和action// System.Web.Mvc.ControllerActionInvokerprotected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters){ ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters); Func<ActionExecutedContext> seed = () => new ActionExecutedContext(controllerContext, actionDescriptor, false, null) { //执行action Result = this.InvokeActionMethod(controllerContext, actionDescriptor, parameters) }; //反序filters,以active执行的seed为基础,累加计算filters得到一个 ActionExecutedContext //这里面就是重点了,大概的意思是先执行所有过滤器,最后执行active,如果中途过滤器产生了Context.Result,则不会继续执行后面的过滤器和active, Func<ActionExecutedContext> func = filters.Reverse<IActionFilter>() .Aggregate(seed, (Func<ActionExecutedContext> next, IActionFilter filter) => () => ControllerActionInvoker.InvokeActionMethodFilter(filter, preContext, next)); return func();}// System.Web.Mvc.ControllerActionInvokerinternal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func<ActionExecutedContext> continuation){ //调用OnActionExecuting filter.OnActionExecuting(preContext); if (preContext.Result != null) { return new ActionExecutedContext(preContext, preContext.ActionDescriptor, true, null) { Result = preContext.Result }; } bool flag = false; ActionExecutedContext actionExecutedContext = null; try { //真正的执行action actionExecutedContext = continuation(); } catch (ThreadAbortException) { actionExecutedContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false, null); filter.OnActionExecuted(actionExecutedContext); throw; } catch (Exception exception) { flag = true; actionExecutedContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false, exception); filter.OnActionExecuted(actionExecutedContext); if (!actionExecutedContext.ExceptionHandled) { throw; } } if (!flag) { filter.OnActionExecuted(actionExecutedContext); } return actionExecutedContext;} |
从以上代码我们可以看出,一个action的执行流程是这样的:
1>根据请求获取Controller和action的信息
2>获取应该有的过滤器
3>Authorization验证,如果不通过则返回
4>ValidateRequest,验证请求数据
5>执行过滤器和active,如果在中途过滤器产生Result,则后面的过滤器和active将不会执行!
所以,最正确的方法就是在过滤器中赋值Result!
ASPNET Core ActionFilterAttribute中断后续请求的更多相关文章
- AspNet Core Swagger4.0 生成请求model描述
今天给大家分享 swagger 俩个冷门的小技巧 获取控制器描述 将 IncludeXmlComments 方法第二个参数设置为 true 即可 public static void IncludeX ...
- ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击
什么是反伪造攻击? 跨站点请求伪造(也称为XSRF或CSRF,发音为see-surf)是对Web托管应用程序的攻击,因为恶意网站可能会影响客户端浏览器和浏览器信任网站之间的交互.这种攻击是完全有可能的 ...
- ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击 (转载)
什么是反伪造攻击? 跨站点请求伪造(也称为XSRF或CSRF,发音为see-surf)是对Web托管应用程序的攻击,因为恶意网站可能会影响客户端浏览器和浏览器信任网站之间的交互.这种攻击是完全有可能的 ...
- NET Core 防止跨站请求
ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击 什么是反伪造攻击? 跨站点请求伪造(也称为XSRF或CSRF,发音为see-surf)是对Web托管应用程序的攻击,因为恶意网站可 ...
- AspNet Core 初步认识
Core 的出现对我我没有很大的影响,当时在Core要发布的时候听到周围的人再聊再谈,我没有去太多关注,就是一个屌丝开发人员. 直到又一次偶然见到一位特别喜欢.net的老开发人员谈起Core时落泪了, ...
- AspNet Core Api Restful +Swagger 发布IIS 实现微服务之旅 (二)
上一步我们创建好CoreApi 接下来在框架中加入 Swagger 并发布 到 IIS (1)首先点击依赖项>管理Nuget包 (2)输入 Swashbuckle.aspnetCore 比 ...
- AspNet Core Api Restful +Swagger 实现微服务之旅 (三)
(1) 访问Rest ful接口时 Token验证 返回数据格式封装 (一)访问时Token验证 返回数据格式封装 1.1访问Api接口 方法 实现 1.1.1 创建访问Rest ...
- AspNet Core 下利用普罗米修斯+Grafana构建Metrics和服务器性能的监控 (无心打造文字不喜勿喷谢谢!)
概述 Prometheus的主要特点 组件 结构图 适用场景 不适用场景 安装node_exporter,系统性能指数收集(收集系统性能情况) 下载文件 解压并复制node_exporter应用程序到 ...
- AspNet Core Api Restful +Swagger 发布IIS
上一步我们创建好CoreApi 接下来在框架中加入 Swagger 并发布 到 IIS (1)首先点击依赖项>管理Nuget包 (2)输入 Swashbuckle.aspnetCore 比 ...
- ASP.NET Core 如何记录每次请求的Request信息 - sky 胡萝卜星星 - CSDN博客
原文:ASP.NET Core 如何记录每次请求的Request信息 - sky 胡萝卜星星 - CSDN博客 版权声明:本文为starfd原创文章,转载请标明出处. https://blog.csd ...
随机推荐
- 杭电oj 进制转换
Problem Description 输入一个十进制数N,将它转换成R进制数输出. Input 输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=1 ...
- Launchpad是什么?Launchpad使用教程
Launchpad是什么?Launchpad 是用来查找和打开Mac系统下的 app 的最快捷方式,通过 Launchpad,您可以查看.整理并轻松打开Mac里面几乎所有的应用软件.下面带来Mac ...
- iview、render使用方法
1.<Table size="large" :columns="columns7" :data="labelInput.label" ...
- kafak学习总结
高可用 多副本机制: 主副本和从副本,从副本只负责同步主副本数据,只有主副本进行读写. 高并发 网络结构设计 多路复用 多selector -> 多线程-> 多队列 高性能 写 把数据先写 ...
- docker之rabbitmq delayed message exchange
创建dockerfile FROM rabbitmq:3.9.11-management-alpine COPY rabbitmq_delayed_message_exchange-3.9.0.ez ...
- [Swift] 在 OC 工程中,创建和使用 Swift
1.我们创建了一个 Objective-C 的工程,叫做 playGround. 2.首先,我们需要在 工程的 Build Settings,找到 如中所示的项目,并将 Defines Module ...
- TCAM and CAM memory usage inside networking devices(转)
TCAM and CAM memory usage inside networking devices Valter Popeskic Equipment and tools, Physical la ...
- Hadoop环境的搭建
Hadoop HDFS.Yarn.MapReduce Hadoop集群环境搭建 完全分布式环境,伪分布式将其中的多台服务器改为一台,并将配置文件中的相关内容更改即可 1.安装Linux系统模型机 关闭 ...
- Vue I18n Vue.js 的国际化插件+elementUI的使用
先附上插件官网 vue-i18n中文官网 我们的vue项目需要支持多语言时,可以使用这个插件 安装插件教程在官网可以找到 代码结构可以如下 zh.js 查看代码 export default { lo ...
- LocalDateTime 使用记录
1.LocalDateTime 获取指定日期的月初和月末 LocalDateTime firstDayTime = LocalDate.now().withMonth(12).withDayOfMon ...