在asp.net MVC中,Action过滤器是一大利器,它可以在以下两个步骤执行相关的代码:

1.执行Action方法之前:OnActionExecuting

2.Action方法执行完毕后:OnActionExecuted

一般我们自定义的Action过滤器会继承FilterAttribute类和IActionFilter接口。

FilterAttribute类有两个关键属性:

AllowMultiple:布尔型,指示是否可指定筛选器特性的多个实例。如果可指定筛选器特性的多个实例,则为 true;否则为 false。

Order:int整型,获取或者设置执行操作筛选器的顺序。该属性后面会讲到。

IActionFilter接口有两个关键方法:

void OnActionExecuting(ActionExecutingContext filterContext):在进入Action之前执行该方法。

void OnActionExecuted(ActionExecutedContext filterContext):Action方法执行完毕之后立刻执行该方法。

接下来让我们用代码亲自实践。

首先自定义一个Action过滤器:

    public class MyFirstActionFilterAttribute : FilterAttribute, IActionFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) {
filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:black;color:white;'>{2} OnActionExecuting {0} {1}</h4>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, this.GetType().Name));
} public void OnActionExecuted(ActionExecutedContext filterContext) {
filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:black;color:white;'>{2} OnActionExecuted {0} {1}</h4>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName,GetType().Name));
}
}

接着我们将该方法过滤器附加到一个Action上:

        [MyFirstActionFilter]
public ActionResult ActionFilterTest() {
Response.Write("进入Action方法");
return new EmptyResult();
}

执行结果如下:

执行的顺序果然是 OnActionExecuting》Action》OnActionExecuted。

如果有很多Action过滤器附加到一个Action方法上,那么执行的顺序又是怎样的呢?相当于自上而下压栈式执行,可以将OnActionExecuting当做左大括号,OnActionExecuted当做右大括号。

我们继续自定义两个Action过滤器来实践一下:

    public class MySecondActionFilterAttribute : FilterAttribute, IActionFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:yellow;color:red;'>{2} OnActionExecuting {0} {1}</h4>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, this.GetType().Name));
} public void OnActionExecuted(ActionExecutedContext filterContext) {
filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:yellow;color:red;'>{2} OnActionExecuted {0} {1}</h4>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, GetType().Name));
}
}
public class MyThirdActionFilterAttribute : FilterAttribute, IActionFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) {
filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:aliceblue;color:blue;'>{2} OnActionExecuting {0} {1}</h4>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, this.GetType().Name));
} public void OnActionExecuted(ActionExecutedContext filterContext) {
filterContext.HttpContext.Response.Write(string.Format("<h4 style='background-color:aliceblue;color:blue;'>{2} OnActionExecuted {0} {1}</h4>",
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, GetType().Name));
}
}

附加到同一个Action方法上:

        [MyFirstActionFilter]
[MySecondActionFilter]
[MyThirdActionFilter]
public ActionResult ActionFilterTest() {
Response.Write("进入Action方法");
return new EmptyResult();
}

执行的结果如下图所示:

执行的顺序果然是自上而下、压栈式执行。这是默认的方式。

我们还可以通过设置每个Action过滤器的Order属性来自定义它们的执行顺序。这就是Action过滤器需要继承FilterAttribute的原因。

接下来我们打乱每个Action过滤器的位置,并设置每个Action过滤器的Order属性。如下代码:

        [MyThirdActionFilter(Order = )]
[MySecondActionFilter(Order = )]
[MyFirstActionFilter(Order =)]
public ActionResult ActionFilterTest() {
Response.Write("进入Action方法");
return new EmptyResult();
}

运行程序,看一看执行的结果:

果然是根据Order的升序来执行的,且还是压栈式执行。

介绍一个实际的用法。如果遇到跨域的情况,可以在OnActionExecuting方法中判断当前用户码和相关标识,表示是否可以跨域处理。

类似如下代码:

        public void OnActionExecuting(ActionExecutingContext filterContext) {
bool isAllowCrossDomain = false;
//判断用户码和相关标识
//......
//判断完毕并设置isAllowCrossDomain
//如果允许跨域
if (isAllowCrossDomain) {
//在此返回正确结果
}
else {
//返回错误代码和消息说明
}
filterContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
}

asp.net MVC之Action过滤器浅析的更多相关文章

  1. asp.net MVC之Result过滤器浅析

    在asp.net MVC中,每一个Action方法完成之后都会返回一个结果,而我们可以在Result过滤器中根据需要修改这个结果.例如可以根据UserAgent来判断客户端的来源是手机还是PC端,从而 ...

  2. Asp.Net MVC<五>:过滤器

    ControllerActionInvoker在执行过程中除了利用ActionDescriptor完成对目标Action方法本身的执行外,还会执行相关过滤器(Filter).过滤器采用AOP的设计,它 ...

  3. ASP.NET MVC学习之过滤器篇(2)

    下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习. 3.动作过滤器 顾名思义,这个过滤器就是在动作方法调用前与调用后响应的.我们可以在调用前更改实际调用的动作,也可以在动作调用完成 ...

  4. 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 ...

  5. 理解ASP.NET MVC Framework Action Filters

    原文:http://www.cnblogs.com/darkdawn/archive/2009/03/13/1410477.html 本指南主要解释action filters,action filt ...

  6. ASP.NET MVC – 关于Action返回结果类型的事儿(上)

    原文:ASP.NET MVC – 关于Action返回结果类型的事儿(上) 本文转自:博客园-文超的技术博客 一.         ASP.NET MVC 1.0 Result 几何? Action的 ...

  7. 返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test

    原文:返璞归真 asp.net mvc (5) - Action Filter, UpdateModel, ModelBinder, Ajax, Unit Test [索引页] [源码下载] 返璞归真 ...

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

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

  9. asp.net MVC之 自定义过滤器(Filter) - shuaixf

    一.系统过滤器使用说明 1.OutputCache过滤器 OutputCache过滤器用于缓存你查询结果,这样可以提高用户体验,也可以减少查询次数.它有以下属性: Duration :缓存的时间, 以 ...

随机推荐

  1. HeadFirst Ruby 第十四章总结 Web apps: Serving HTML

    前言 这一章节主要讲了如何利用 Ruby 中的 Sinatra 这个 gem 来创建一个 Web app 的具体流程,其中的要点包括了: Sinatra, a third party library ...

  2. Django多表查询练习题

    #一 model表:from django.db import models # Create your models here. class Teacher(models.Model): tid=m ...

  3. 模拟curl函数

    只要需要调用微信的网址,就需要模拟curl请求 $tokenUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_cr ...

  4. dp 最大正方形

    洛谷P1387 最大正方形 分析:画图模拟,发现以坐标(i,j)为右下顶点的正方形可以根据它左上方的三个点得到,就很轻松写出状态转移方程了. 代码: #include<bits/stdc++.h ...

  5. 精华 selenium_webdriver(python)调用js脚本

    #coding=utf-8 from selenium import webdriver import time driver = webdriver.Firefox() driver.get(&qu ...

  6. Guarding Bananas

    Guarding Bananas Once there was a lazy monkey in a forest. But he loved banana too much. One day the ...

  7. RocketMQ消息存储

    转载:RocketMQ源码学习--消息存储篇 消息中间件—RocketMQ消息存储(一) RocketMQ高性能之底层存储设计 存储架构 RMQ存储架构 上图即为RocketMQ的消息存储整体架构,R ...

  8. python3+ftplib实现ftp客户端

    一.程序说明 1.1 程序实现关键点 python实现ftp客户端,主要会遇到以下四个问题: 第一个问题是使用什么包实现----我们这里是使用标准库中的ftplib 第二个问题是怎么连接登录ftp服务 ...

  9. redis集群搭建教程(以3.2.2为例)

    redis从3.0版本开始支持集群,2.X版本主支持sentinel主从模式:所以要搭建集群务必下载3.0以上版本,本教程以3.2.2版本为例. redis集群最少要有3个主节点,最典型的是3主3从组 ...

  10. [转]perftools查看堆外内存并解决hbase内存溢出

    最近线上运行的hbase发现分配了16g内存,但是实际使用了22g,堆外内存达到6g.感觉非常诡异.堆外内存用一般的工具很难查看,可以通过google-perftools来跟踪: http://cod ...