专栏首页张善友的专栏ASP.NET MVC的Action Filter

ASP.NET MVC的Action Filter

一年前写了一篇短文ASP.NET MVC Action Filters,整理了Action Filter方面的资源,本篇文章详细的描述Action Filter。Action Filter作为一个可以应用到Controller Action(或者是整个controller)上的属性(Attribute),改变Action执行的行为,当应用于整个Controller上时,Controller上的所有Action都应用了同样设置的Action。 使用Action Filter 可以处理缓存、 验证和错误处理您的操作使用声明性编程模型的行为。

ASP.NET MVC Framework支持四种不同类型的Filter:

  1. Authorization filters – 实现IAuthorizationFilter接口的属性.
  2. Action filters – 实现IActionFilter接口的属性.
  3. Result filters – 实现IResultFilter接口的属性.
  4. Exception filters – 实现IExceptionFilter接口的属性.

Filter的默认的执行顺序按上面的列表中顺序进行。如验证(authorization)Filter永远都是最开始执行的,异常(exception)Filter永远都是最后执行的,当然你也可以根据需要通过Order属性设定过滤器执行的顺序。

ASP.NET MVC Framework包括几种Action Filter:

名称

说明

OutputCacheAttribute

类似于 Web Form中在 OutputCache 指令。 OutputCache 属性允许在 MVC Framework 缓存控制器的输出。

ValidateInputAttribute

类似于 Web Form中 ValidateRequest 属性。 MVC 框架默认将为 检查HTML 或其他危险输入传入的 HTTP 请求。 如果检测到,将引发异常。 使用此属性可以禁用请求验证。

AuthorizeAttribute

Authorize 属性,可以对控制器操做的声明性的授权检查。 该属性可以限制特定角色中的用户的操作。 当您创建只应该给管理员角色中的用户的操作时,您可以使用此属性。默认使用的ASP.NET Membership服务,如果不使用ASP.NET 的Membership服务,可以继承AuthorizeAttribute,重写实现。

ValidateAntiForgeryTokenAttribute

此属性是一个解决方案以帮助防止跨站点的请求攻击 (CSRF)。 它允许验证的 HTTP POST 为特定于用户的标记在 Framework。 有关详细信息 CSRFs,请参阅" 使用 ASP.NET MVC AntiForgeryToken() 帮助器防止跨站点请求伪造 (CSFR)."

验证(authorization)filter用于实现在controller action上的验证和授权,如Authorize filter就是一个验证filter的例子;

Action filter包含一些逻辑,用于该action执行之前或者之后。比如可以使用一个action filter来修改action返回的view data;

Result filter包含一些逻辑,用于该action的view result执行之前和之后。比如可以修改一个view result在view被呈现到浏览器之前;

异常(Exception)Action用于处理异常信息,同样可以使用异常filter记录错误日志。

你同时可以创建自己的Action filter,比如说要实现一个自定义的验证系统,那么可能需要创建一个自定义的action filter,或者说当你需要改变controller action返回的view data的时候,也可以通过创建自定义action filter实现。

为了让用户更简单的创建一个自定义Action filter,ASP.NET MVC Framework提供了一个基类ActionFilterAttribute,这个类实现了IActionFilter和IResultFilter接口,并且继承了FilterAttribute类。从广义上来说,在ASP.NET MVC Framework中,任何实现filter的类型都是action filter。

ActionFilterAttribute类有以下的方法可以重写:

  • OnActionExecuting – 在controller action执行之前调用
  • OnActionExecuted – 在controller action执行之后调用
  • OnResultExecuting – 在controller action result执行之前调用
  • OnResultExecuted – 在controller action result执行之后调用

执行的顺序如下图:

下面我们来介绍一个如何自定义一个Action Filter,这个示例的代码来自ASP.NET MVC 2示例Tailspin Travel,实现的功能是Action的执行时间,页面经常需要一个当前页面执行时间的功能,这是一个非功能性需求,ASP.NET MVC上就可以使用自定义的ActionFilter来实现,从上面的介绍,就知道我们需要重写OnActionExecuting和OnActionExecuted方法,代码如下:

namespace Microsoft.Samples.Tailspin.Web    
{     
    using System.Configuration;     
    using System.Diagnostics;     
    using System.Globalization;     
    using System.Web.Mvc; 
    public class ExecutionTimingAttribute : ActionFilterAttribute    
    {     
        private bool timingEnabled = bool.Parse(ConfigurationManager.AppSettings["TimingEnabled"]);     
        private Stopwatch timer; 
        public override void OnActionExecuting(ActionExecutingContext filterContext)    
        {     
            base.OnActionExecuting(filterContext);     
            if (this.timingEnabled)     
            {     
                this.timer = new Stopwatch();     
                this.timer.Start();     
            }     
        } 
        public override void OnActionExecuted(ActionExecutedContext filterContext)    
        {     
            base.OnActionExecuted(filterContext);     
            if (this.timingEnabled)     
            {     
                this.timer.Stop();     
                Trace.WriteLine(string.Format(CultureInfo.InvariantCulture, "Action execution time: {0}ms", this.timer.ElapsedMilliseconds));     
                if (filterContext.Result is ViewResult)     
                {     
                    ((ViewResult)filterContext.Result).ViewData["ExecutionTime"] = this.timer.ElapsedMilliseconds;     
                }     
            }     
        }     
    }     
}

通过一个配置项是否启用页面执行时间的控制,代码非常简单,使用Stopwatch来进行时间的计算,将执行的时间(毫秒为单位)存放到ViewData里ViewData["ExecutionTime"] 。 在MasterPage里头尾部加入:

<div id="footer">    
        <% if(ViewData.ContainsKey("ExecutionTime")) { %>     
            <p>Execution Time: <%:ViewData["ExecutionTime"]%> ms.</p>     
        <%} %>     
    </div>

參考

Creating Custom Action Filters

Understanding Action Filters

asp.MVC 权限设计

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • .NET 十五岁,谈谈我眼中的.NET

    2002年2月13日,第一个版本随着visual studio.net的发布,今天已经走过15年, .net团队写了一篇文章,里面有一个视频,Anders He...

    张善友
  • .NET Core 2.1 Preview 2发布 - April 10, 2018

    张善友
  • .NET和Docker ,比翼双飞

    DockerCon 2019本周将在旧金山举行 ,DockerCon 是从业者、贡献者、维护者、开发者和容器生态系统学习、网络和创新的一站式活动。 .NET 团...

    张善友
  • 一个Mini的ASP.NET Core框架的实现

      在2019年1月的微软技术(苏州)俱乐部成立大会上,蒋金楠老师(大内老A)分享了一个名为“ASP.NET Core框架揭秘”的课程,他用不到200行的代码实...

    Edison Zhou
  • SQL优化案例 | 从Exadata迁移到国产沃趣一体机一般方法探究(四)

    存储技术的发展,闪存的出现,大大提升了数据库一体机的性能,随着闪存成本的降低,我相信未来Exadata也不会再有flashcache、flashlog相关的特性...

    沃趣科技
  • LTS(Long-term Support)是怎样的一种支持方式

    2018-07-04 13:29

    walterlv
  • 【经验分享】做计算机视觉的你,如何拿到大厂的Offer的?

    楼主研二计算机视觉方向的,水平不高,实习面试被拒,好奇大家是怎么利用自己的专业知识拿到Offer的?

    AI算法与图像处理
  • SQL IN 一定走索引吗?

    IN 一定走索引吗?那当然了,不走索引还能全部扫描吗?好像之前有看到过什么Exist,IN走不走索引的讨论。但是好像看的太久了,又忘记了。哈哈,如果你也忘记了M...

    方丈的寺院
  • 云端家长会,给佤山留守儿童的特殊六一礼物

    ? ? 6岁的嘉乐许了一个愿望:我要飞到天空上,看看我爸爸。 2年前,嘉乐的妈妈离开家后,就再也没有出现。随后,爸爸只身赴广东打工,留下年幼的男孩和爷爷奶奶一...

    鹅老师
  • grpc 使用流程、使用技巧

    1、通过maven插件编译出java stub类。 2、对于批量调用的场景,我们可以使用FutureStub,对于普通的业务类型RPC,我们应该使用Blocki...

    杉枫

扫码关注云+社区

领取腾讯云代金券