前言

前面两篇写的比较简单,刚开始写这个系列的时候我面向的对象是刚开始接触Asp.Net MVC的朋友,所以写的尽量简单。所以写的没多少技术含量。把这些技术总结出来,然后一简单的方式让更多的人很好的接受这是我一直努力的方向。后面会有稍微复杂点的项目!让我们一起期待吧!

此文我将跟大家介绍一下Asp.Net MVC3 Filter的一些用法。你会了解和学习到全局Fileter,Action Filter等常用用法。

第一节:Filter知识储备

项目大一点总会有相关的AOP面向切面的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中呢Action在执行前或者执行后我们想做一些特殊的操作(比如身份验证,日志,异常,行为截取等),而不想让MVC开发人员去关心和写这部分重复的代码,那我们可以通过AOP截取实现,而在MVC项目中我们就可以直接使用它提供的Filter的特性帮我们解决,不用自己实现复杂的AOP了。

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的类型,所以不能直接使用,因为它不能实例化,所以我们想使用它必须继承一下它然后才能使用,下图所示的是ActionFilterAttribute的实现:

所以我们在实现了ActionFilterAttribute,然后就可以直接重写一下父类的方法如下:


publicvirtualvoid OnActionExecuted(ActionExecutedContext filterContext);//在Action执行之后执行 

publicvirtualvoid OnActionExecuting(ActionExecutingContext filterContext); //在Action执行前执行

publicvirtualvoid OnResultExecuted(ResultExecutedContext filterContext);//在Result执行之后 

publicvirtualvoid OnResultExecuting(ResultExecutingContext filterContext); //在Result执行之前

然后我们就可以直接在Action、Result执行之前之后分别做一些操作。

第二节:Action Filter实战

光说不练假把式,那现在我们就直接做一个例子来实际演示一下。

首先我们添加一个普通的类,直接上代码吧:


publicclass DemoActionAttributeFilter : ActionFilterAttribute
{
publicstring Message { get; set; } publicoverridevoid OnActionExecuted(ActionExecutedContext filterContext)
{ //在Action执行之后执行 输出到输出流中文字:After Action execute xxx
filterContext.HttpContext.Response.Write(@"<br />After Action execute"+"\t "+ Message);
base.OnActionExecuted(filterContext);
} publicoverridevoid OnActionExecuting(ActionExecutingContext filterContext)
{ //在Action执行前执行
filterContext.HttpContext.Response.Write(@"<br />Before Action execute"+"\t "+ Message);
base.OnActionExecuting(filterContext);
} publicoverridevoid OnResultExecuted(ResultExecutedContext filterContext)
{ //在Result执行之后 
filterContext.HttpContext.Response.Write(@"<br />After ViewResult execute"+"\t "+ Message);
base.OnResultExecuted(filterContext);
} publicoverridevoid OnResultExecuting(ResultExecutingContext filterContext)
{ //在Result执行之前
filterContext.HttpContext.Response.Write(@"<br />Before ViewResult execute"+"\t "+ Message);
base.OnResultExecuting(filterContext);
} }

写完这个代码后,我们回到Action上,打上上面的标记如下所示:

[DemoActionAttributeFilter(Message ="action")]
public ActionResult Index()
{ //Action 执行时往输出流写点代码
this.ControllerContext.HttpContext.Response.Write(@"<br />Action execute");
return Content("Result Excut! ");
}

然后执行F5,页面上则会显示为:

最终我们看到了在Action执行之前和之后都执行了我们的重写的DemoActionAttributeFilter方法,Result执行前后也执行了我们的Filter的方法。

总的执行顺序是:

Action执行前:OnActionExecuting方法先执行→Action执行→OnActionExecuted方法执行→OnResultExecuting方法执行→返回的ActionRsult中的executeResult方法执行→OnResultExecuted执行。最终显示的效果就是如上图所示。

感觉很爽吧!呵呵!

如果我们将此标签打到Controller上的话,DemoActionAttributeFilter将作用到Controller下的所有的Action。例如如下代码所示:


[DemoActionAttributeFilter(Message ="controller")]
publicclass HomeController : Controller
{
[DemoActionAttributeFilter(Message ="action")]
public ActionResult Index()
{
this.ControllerContext.HttpContext.Response.Write(@"<br />Action execute");
return Content("<br/>Result Excut! ");
}
}
 
那就有个问题了我们再执行显示的页面会有什么情况呢?Controller上的Filter会执行吗?那标签的作用会执行两次吗?下面是最后的执行结果如下图所示:

结果说明:默认情况下Action上打了DemoActionAttributeFilter 标签后,虽然在Controller上也打上了此标签,但它只有Action上的标签起作用了。

Index 执行时,Filter的方法只执行了一次,而某些情况下我们也想让Controller上的FilterAttribute也执行一次DemoActionAttributeFilter

那我们怎么才能让Controller上的[DemoActionAttributeFilter(Message = "controller")]也起作用呢?

答案是:我们只需在DemoActionAttributeFilter类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]即可【下面类的最上面红色字体部分】,也就是让其成为可以多次执行的Action。代码如下:


[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
publicclass DemoActionAttributeFilter : ActionFilterAttribute
{
publicstring Message { get; set; } publicoverridevoid OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write(@"<br />After Action execute"+"\t "+ Message);
base.OnActionExecuted(filterContext);
} publicoverridevoid OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write(@"<br />Before Action execute"+"\t "+ Message);
base.OnActionExecuting(filterContext);
} publicoverridevoid OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write(@"<br />After ViewResult execute"+"\t "+ Message);
base.OnResultExecuted(filterContext);
} publicoverridevoid OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write(@"<br />Before ViewResult execute"+"\t "+ Message);
base.OnResultExecuting(filterContext);
} }

然后我们执行的效果如图所示:

我们看到的结果是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执行→结束

第三节:Gloable Filter实战

又接着一个问题也来了,我们想有些公共的方法需要每个Action都执行以下,而在所有的Controller打标记是很痛苦的。幸好Asp。Net MVC3带来了一个美好的东西,全局Filter。而怎么注册全局Filter呢?答案就在Global.asax中。让我们看以下代码,我是如何将上面我们定义的DemoActionAttributeFilter 注册到全局Filter中。上代码:


publicclass MvcApplication : System.Web.HttpApplication
{
publicstaticvoid RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
} publicstaticvoid RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller ="Home", action ="Index", id = UrlParameter.Optional } // Parameter defaults
); } protectedvoid Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalFilters.Filters.Add(new DemoActionAttributeFilter() { Message = "Gloable" });
RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes);
}
}

跟普通的MVC2.0中的Global.asax的区别就是红色部分的代码,我们看到代码中我将自己定义的DemoActionAttributeFilter的实例加入到GlobalFilters.Filters集合中,然后下面一句就是注册全局Filter:RegisterGlobalFilters(GlobalFilters.Filters);

这样我们所有的Action和Result执行前后都会调用我们的DemoActionAttributeFilter的重写的方法。

再次运行我们的demo看到的结果是:

我们看到的结果是全局的Action首先执行,然后才是Controller下的Filter执行,最后才是Action上的标签执行。当然这是在DemoActionAttributeFilter类的定义上打上标记[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]的前提下。不然 如果Action打上了标签跟Controller的相同则它只会执行Action上的Filter。

总结

经过这一篇文章的介绍我们大体了解了Filter的使用方法,还了解到全局Filter的用法,尤其是当相同的Filter重复作用到同一个Action上时,如果没有设置可多次执行的标签那只有Action上的Filter执行,而Controller和全局Filter都被屏蔽掉,但是设置可多次执行,那首先执行全局Filter其次是Controller再次之就是Action上的Filter了。

本文提供Word版本下载地址:http://files.cnblogs.com/fly_dragon/Filter%E5%AD%A6%E4%B9%A0.rar

记于:2011年6月14日23:23:47

初识Asp.Net MVC2.0

初识Asp.Net MVC2.0【续】

Asp.Net MVC2.0 Url 路由入门---实例篇

Asp.Net MVC2.0 Url 路由入门

Asp.Net MVC3 简单入门第一季(一)环境准备

Asp.Net MVC3 简单入门第一季(二)详解Asp.Net MVC3项目

Asp.Net MVC3 简单入门第一季(三)详解Controller之Filter

Asp.Net MVC3 简单入门第一季(四)详解Request Processing Pipeline

作者:FlyDragon

出处:http://www.cnblogs.com/fly_dragon/

关于作者:专注于微软平台项目架构、管理和企业解决方案。如有问题或建议,请多多赐教!

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通malun666@126.com 联系我,非常感谢。

Asp.Net MVC3 简单入门第一季(三)详解Controller之Filter的更多相关文章

  1. [MVC.NET] Asp.Net MVC3 简单入门第一季

    转自:http://www.cnblogs.com/fly_dragon/archive/2011/10/12/2208042.html 初识Asp.Net MVC2.0 初识Asp.Net MVC2 ...

  2. Asp.Net MVC3 简单教程(三)详解Controller之Filter 【转】

    前言 前面两篇写的比较简单,刚开始写这个系列的时候我面向的对象是刚开始接触Asp.Net MVC的朋友,所以写的尽量简单.所以写的没多少技术含量.把这些技术总结出来,然后一简单的方式让更多的人很好的接 ...

  3. Asp.Net MVC3 简单入门详解过滤器Filter(转)

    前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码 ...

  4. Asp.Net MVC3 简单入门详解过滤器Filter

    http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MV ...

  5. 【转】Asp.Net MVC3 简单入门详解过滤器Filter

    原文地址:http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组 ...

  6. Asp.Net MVC3 简单入门详解过滤器Filter(转载)

    前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MVC(特指:Asp.Net MVC,以下皆同)项目中不想让MVC开发人员去关心和写类似身份验证,日志,异常,行为截取等这部分重复的代码 ...

  7. 经典ASP.NET MVC3.0入门详解

    http://blog.csdn.net/csh624366188/article/details/7064269 :由于本文原在word文档里编写,写本文章时运用了大量截图,直接复制到博客里,没有显 ...

  8. 【转】asp.net mvc3 简单缓存实现sql依赖

    asp.net mvc3 简单缓存实现sql依赖   议题 随 着网站的发展,大量用户访问流行内容和动态内容,这两个方面的因素会增加平均的载入时间,给Web服务器和数据库服务器造成大量的请求压力.而大 ...

  9. JAVA入门第一季(mooc-笔记)

    笔记相关信息 /** * @subject <学习与创业>作业1 * @author 信管1142班 201411671210 赖俊杰 * @className <JAVA入门第一季 ...

随机推荐

  1. USB-CSW之旅

    前面总结了usb mass storage的枚举过程,如果所有枚举正常,那么会进入bulkonly协议定义的数据交流,在这个数据包里面还包含了SCSI的协议. Bulkonly协议usbmassbul ...

  2. Best Time to Buy and Sell Stock II 解答

    Question Say you have an array for which the ith element is the price of a given stock on day i. Des ...

  3. Floyd 无向图模板

    这是无向图的 void Floyd() { memset(v, 0x3f, sizeof v); ; i <= n; i++) ; j <= n; j++) v[i][j] = map[i ...

  4. 也谈---基于 HTTP 长连接的“服务(转载)

    这里指讨论基于HTTP的推技术, 诸如flash,applet之类的东西不作分析, 他们就不能说是"纯粹"的浏览器应用了. 首先是一点背景知识, 大家都知道长连接避免了tcp连接的 ...

  5. Tomcat可以在eclipse里启动,可是不能訪问首页的问题

    今天在使用eclipse的时候发现一个问题.就是我在eclipse里面已经启动了tomcat.部署上去的项目也能够启动,可是就是没法訪问tomcat的首页.port等等都没有问题. 后来查到解决方式, ...

  6. SVN中tag branch trunk用法详解

    SVN中tag branch trunk用法详解 2010-05-24 18:32 佚名 字号:T | T 本文向大家简单介绍一下SVN中tag branch trunk用法,SVN中tag bran ...

  7. zookeeper 丢失事件/miss event

    今天在统计页面上发现有个节点丢失了,经过仔细分析后,发现同一个节点上的二个应用(同时监控zk)其中一个丢失了一个event,检查zk cluster没有发现异常... 通过网络搜寻,出现miss ev ...

  8. stagefright框架(三)-选择Video Decode

    在<Stagefright (1) – Video Playback的流程>中,我们并没有详述Stagefright是如何根据影片档的类型来选择适合的video decoder,现在,就让 ...

  9. Java web项目

    前言 本文目标:使用eclipse为IDE环境搭建一个基于maven的web项目,讲解搭建过程,项目结构,程序运行.调试和测试过程,并使用maven作为持续集成工具.     面向对象:转型java的 ...

  10. Sublime Text插件FileHeader实践

    FileHeader是一个文件模板插件,可以定制各种文件模板和文件头部信息,保存时可以自动更新文件的修改时间.在多人开发中这个功能相当实用. 具体介绍我就不细说了,主要是分享一下在使用FileHead ...