Asp.Net MVC3 简单入门详解过滤器Filter(转载)
前言
在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码,那我们可以通过AOP截取实现,而在MVC项目中我们就可以直接使用它提供的Filter的特性帮我们解决,不用自己实现复杂的AOP了。
在Asp.net Mvc中当你有以下及类似以下需求时你可以使用Filter功能
- 判断登录与否或用户权限
- 决策输出缓存
- 防盗链
- 防蜘蛛
- 本地化与国际化设置
- 实现动态Action
第一节:知识储备
Asp.Net MVC提供了以下几种默认的Filter:
|
Filter Type |
实现接口 |
执行时间 |
Default Implementation |
|
Authorization filter |
IAuthorizationFilter |
在所有Filter和Action执行之前执行 |
AuthorizeAttribute |
|
Action filter |
IActionFilter |
分别在Action执行之前和之后执行。 |
ActionFilterAttribute |
|
Result filter |
IResultFilter |
分别在Action Result执行之后和之前 |
ResultFilterAttribute |
|
Exception filter |
IExceptionFilter |
只有在filter, 或者 action method, 或者 action result 抛出一个异常时候执行 |
HandleErrorAttribute |
大家注意一点,Asp.Net MVC提供的ActionFilterAttribute默认实现了IActionFilter和IResultFilter。而ActionFilterAttribute是一个Abstract的类型,所以不能直接使用,因为它不能实例化,所以我们想使用它必须继承一下它然后才能使用。
Filter继承于ActionFilterAttribute抽象类,并可以覆写 void OnActionExecuting(ActionExecutingContext) 和 void OnActionExecuted(ActionExecutedContext) 以及 void OnResultExecuting(ResultExecutingContext)和 void OnResultExecuted(ResultExecutedContext)。
它们的执行先后顺序如下:
OnActionExecuting是Action执行前的操作
OnActionExecuted则是Action执行后的操作
OnResultExecuting是解析ActionResult前执行
OnResultExecuted是解析ActionResult后执行
接下来我们只要对以上的方法进行重写就可以在相应的步骤做一些操作了。
第二节:Filter实战
光说不练假把式,下面我给大家一个示例,来看看它们的执行顺序
首先添加一个普通的类,这个类要继承ActionFilterAttribute,,直接上代码了

public class TestFilterAttribute:ActionFilterAttribute
{
public string Message { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
filterContext.HttpContext.Response.Write("Action执行之前"+Message+"<br />");
} public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
filterContext.HttpContext.Response.Write("Action执行之后"+Message+"<br />");
} public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.Write("返回Result之前"+Message+"<br />");
} public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
filterContext.HttpContext.Response.Write("返回Result之后"+Message+"<br />");
}
}

写完这个代码后,我们回到Action上,打上上面的标记如下所示:
[TestFilter(Message="Action")]
public ActionResult Index()
{
HttpContext.Response.Write("Action正在执行···<br />");
return Content("正在返回Result···<br />");
}
然后通过浏览器访问上面的Action便可以看到下面的执行顺序

总的执行顺序是:
Action执行前:OnActionExecuting方法先执行→Action执行→OnActionExecuted方法执行→OnResultExecuting方法执行→返回的ActionRsult中的executeResult方法执行→OnResultExecuted执行。最终显示的效果就是如上图所示。
感觉很爽吧!呵呵!这要想用到这个过滤机制的地方的时候,只要在Action上面添加标记便可以实现效果。
如果我们将此标签打到Controller上的话,TestFilterAttributeFilter将作用到Controller下的所有的Action。例如如下代码所示:

[TestFilter(Message="Controller")]
public class TestFilterController : Controller
{
//
// GET: /TestFilter/
[TestFilter(Message="Action")]
public ActionResult Index()
{
HttpContext.Response.Write("Action正在执行···<br />");
return Content("正在返回Result···<br />");
} }

如果单纯的按照上面的代码来做就有个问题了我们再执行显示的页面会有什么情况呢?Controller上的Filter会执行吗?那标签的作用会执行两次吗?下面是最后的执行结果如下图所示:

结果说明:默认情况下Action上打了TestFilterAttribute 标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。
补充:如果Action没有打上TestFilterAttribute标签,那么Controller上的标签便会被执行。
Index 执行时,Filter的方法只执行了一次,而某些情况下我们也想让Controller上的FilterAttribute也执行一次TestFilterAttribute,那我们怎么才能让Controller上的[TestFilter(Message = "controller")]也起作用呢?
答案是:我们只需在TestFilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action。代码如下:

[AttributeUsage(AttributeTargets.All,AllowMultiple = true)]
public class TestFilterAttribute:ActionFilterAttribute
{
public string Message { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
filterContext.HttpContext.Response.Write("Action执行之前"+Message+"<br />");
} public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
filterContext.HttpContext.Response.Write("Action执行之后"+Message+"<br />");
} public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.Write("返回Result之前"+Message+"<br />");
} public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
filterContext.HttpContext.Response.Write("返回Result之后"+Message+"<br />");
}
}

浏览效果如下图:

我们看到的结果是Controller上的ActionFilter先于Action上打的标记执行。同样Result执行executeResult方法之前也是先执行Controller上的Filter标记中的OnResultexecuteing方法。
最后的执行顺序是:Controller上的OnActionExecuting→Action上的OnActionExecuting→Action执行→Action上的OnActionExecuted→Controller上的OnActionExecuted
到此Action就执行完毕了,我们看到是一个入栈出栈的顺序。后面是Action返回ActionResult后执行了ExecuteResult方法,但在执行之前要执行Filter。具体顺序为:
接上面→Controller的OnResultExecuting方法→Action上的OnResultExecuting→Action返回ActionResult后执行了ExecuteResult方法→Action上的OnResultExecuted执行→Controller上的OnResultExecuted执行→结束。
又接着一个问题也来了,我们想有些公共的方法需要每个Action都执行以下,而在所有的Controller打标记是很痛苦的。幸好Asp。Net MVC3带来了一个美好的东西,全局Filter。而怎么注册全局Filter呢?答案就在Global.asax中。让我们看以下代码,我是如何将上面我们定义的TestFilterAttribute 注册到全局Filter中。上代码:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
//注册全局过滤器
filters.Add(new TestFilterAttribute() { Message="全局"});
}
效果如下图:

我们看到的结果是全局的Action首先执行,然后才是Controller下的Filter执行,最后才是Action上的标签执行。当然这是在TestFilterAttribute类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]的前提下。不然 如果Action打上了标签跟Controller的相同则它只会执行Action上的Filter。
下面我们说几个系统的Filter
三、AcceptVerbs
规定页面的访问形式,如
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Example(){
return View();
}
页面只能以Post形式访问,即表单提交。
四、ActionName
规定Action的名称。
应用场景:如果不想用方法名做为Action名,或Action名为关键字的话,如
[ActionName("class")]
public ActionResult Example(){
return View();
}
五、NonAction
当前方法仅是普通方法不解析为Action
六、OutputCache
为Action添加缓存
[OutputCache(Duration = 60, VaryByParam = "*")]
public ActionResult Example()
{
return View();
}
七、ValidateInput
该Action可以接受Html等危险代码(ASP.NET MVC在aspx中设置<%@ Page 的属性无法完成等同任务。)
[ValidateInput(false)]
public ActionResult Example()
{
return View();
}
八、ValidateAntiForgeryTokenAttribute
用于验证服务器篡改。
[ValidateAntiForgeryToken]
public ActionResult Example()
{
return View();
}
总结
经过这一篇文章的介绍我们大体了解了Filter的使用方法,还了解到全局Filter的用法,尤其是当相同的Filter重复作用到同一个Action上时,如果没有设置可多次执行的标签那只有Action上的Filter执行,而Controller和全局Filter都被屏蔽掉,但是设置可多次执行,那首先执行全局Filter其次是Controller再次之就是Action上的Filter了。同时还了解了系统的Filter的用法。
来源:https://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html
Asp.Net MVC3 简单入门详解过滤器Filter(转载)的更多相关文章
- Asp.Net MVC3 简单入门详解过滤器Filter(转)
前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码 ...
- Asp.Net MVC3 简单入门详解过滤器Filter
http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MV ...
- 【转】Asp.Net MVC3 简单入门详解过滤器Filter
原文地址:http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组 ...
- 经典ASP.NET MVC3.0入门详解
http://blog.csdn.net/csh624366188/article/details/7064269 :由于本文原在word文档里编写,写本文章时运用了大量截图,直接复制到博客里,没有显 ...
- Asp.Net MVC3 简单入门第一季(三)详解Controller之Filter
前言 前面两篇写的比较简单,刚开始写这个系列的时候我面向的对象是刚开始接触Asp.Net MVC的朋友,所以写的尽量简单.所以写的没多少技术含量.把这些技术总结出来,然后一简单的方式让更多的人很好的接 ...
- [MVC.NET] Asp.Net MVC3 简单入门第一季
转自:http://www.cnblogs.com/fly_dragon/archive/2011/10/12/2208042.html 初识Asp.Net MVC2.0 初识Asp.Net MVC2 ...
- SQL注入攻防入门详解
=============安全性篇目录============== 本文转载 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机 ...
- SQL注入攻防入门详解(2)
SQL注入攻防入门详解 =============安全性篇目录============== 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱 ...
- [转]SQL注入攻防入门详解
原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============ ...
随机推荐
- android 学习网站
菜鸟教程 http://www.runoob.com/android/android-tutorial.html Android基础入门教程 http://www.runoob.com/w3cnot ...
- hdu 1290_献给杭电五十周年校庆的礼物
Description 或许你曾经牢骚满腹或许你依然心怀忧伤或许你近在咫尺或许你我天各一方 对于每一个学子母校 永远航行在生命的海洋 今年是我们杭电建校五十周年,这是一个值得祝福的日子.我们该送给母校 ...
- Html5与Css3知识点拾遗(五)
css3更新的颜色 RGBA:红.绿.蓝.不透明度 rgba(89,0,127,0.4); HSL和HSLA:色相.饱和度.亮度.不透明度 hsl(282,100%,25%); hsl(282,100 ...
- PHP字符串函数之 strcmp strncmp strcasecmp strncasecmp strnatcmp strnatcasecmp
strcmp – 二进制安全字符串比较 strncmp – 二进制安全比较字符串开头的若干个字符 strcasecmp – 二进制安全比较字符串(不区分大小写) strncasecmp – 二进制安全 ...
- Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
原文出处: 海子 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅 ...
- windows 批处理语言学习
程序员应该根植于心的一个理念是:重复的工作交给代码.windows上的批处理脚本就是这种理念的体现. 批处理bat能做的事很多,自动配置vs工程中的代码依赖环境,调用其它程序处理数据.自动编译代码等等 ...
- js中的柯里化
概述 今天查询事件绑定资料的时候偶然遇到了柯里化这个词,很感兴趣,于是记录下来供以后开发时参考,相信对其他人也有用. 定义 柯里化是函数式编程里面的术语,它是把接受多个参数的函数变换成接受一个单一参数 ...
- ElasticSearch权威指南学习(结构化查询)
请求体查询 简单查询语句(lite)是一种有效的命令行adhoc查询.但是,如果你想要善用搜索,你必须使用请求体查询(request body search)API. 空查询 我们以最简单的 sear ...
- Linux 系统资源管理-top-cpu
- 数组的三种声明方式总结、多维数组的遍历、Arrays类的常用方法总结
1. 数组的三种声明方式 public class WhatEver { public static void main(String[] args) { //第一种 例: String[] test ...