一步步学习ASP.NET MVC3 (15)——过滤器
请注明转载地址:http://www.cnblogs.com/arhat
今天老魏和大家一起讨论一下ASP.NET MVC中非常重要的一个知识:“过滤器”。那么这个“过滤器”乍一听好像在ASP.NET中并没有这个东东,反而在J2EE中常常提到这个知识,其实在传统的ASP.NET中是存在“过滤器”的,只不过我们平时并没有注意到它。反而到ASP.NET MVC中,这个“过滤器”就提到一个非常重要的位置。“过滤器”可以使我们在实现某些操作的时候非常的重要,如果没有“过滤器”那么实现某些功能的时候就比较困难,比如登录验证等操作,或者是处理一些敏感的数据。
那么下面我们看看什么是“过滤器”。从名字上看“过滤器”的意思是就是把一些不需要东西给过滤掉,其实就像我们平时的下水管道一样,有一个过滤网,这个过滤网就是把一下事物残渣过滤掉,防止堵塞下水管道。那么在ASP.NET MVC中的“过滤器”也是这个作用。
只不过在ASP.NET MVC过滤器中所过滤的不是水,而是一个HttpRequest.而食物残渣就好比是HttpRequest所带的数据,我们可以定义一下过滤器的规则,把不需要的数据给过滤掉,只把合法的数据传递到服务器中并处理。
在Asp.net Mvc中当你有以下及类似以下需求时你可以使用Filter功能
1. 判断登录与否或用户权限
2. 决策输出缓存
3. 防盗链
4. 防蜘蛛
5. 本地化与国际化设置
6. 实现动态Action
上面说了那么多文字内容,可能还是不是很清楚过滤器所处的位置,那么下面我们通过一个图来了解一下这个“过滤器”。

这个图是老魏自己画的,没有采用微软的图。在浏览器发送请求的时候,这个请求会会在执行Action之前先过滤一下这个请求,把合法内容留下并传递给Aciton执行,当执行完毕之后服务器把处理结果发送给浏览器之前也就是执行Action之后还得在经历一个过滤器,这个过滤器可以什么都不做,也可以对Action的执行结果进行修改再次的发送给浏览器。这个就是过滤器的执行过程。
在APS.NET MVC中提供几种默认的过滤器。
| 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 |
这四种过滤器AuthorizeAttribute,ActionFilterAttribute,ResultFilterAttribute,HandleErrorAttribute都是ASP.NET MVC提供的默认过滤器。如果我们要使用这些过滤器的时候,需要继承这些类。由于这些类都是Attribute,所以我们的子类必须是以Attribute结尾的。
那么我们以ActionFilterAttribute为例来介绍一下过滤器。这个过滤器是针对Action的,那么这个Attribute必须只能作用于Action,也就是在Action执行之前,执行之后的过滤器。
在ActionFilterAttribute中,提供了四种方法来处理Action的请求过滤。
//在Action执行之后 public virtual void OnActionExecuted(ActionExecutedContext filterContext); //在Action执行之前 public virtual void OnActionExecuting(ActionExecutingContext filterContext); //解析ActionResult前执行 public virtual void OnResultExecuted(ResultExecutedContext filterContext); //解析ActionResult后执行 public virtual void OnResultExecuting(ResultExecutingContext filterContext);
我们来试验一下,在我们的项目中创建一个文件夹Filter用来存放我们的过滤器。

首先,我们在Filter文件夹中创建一个过滤器“MyActionFilter.cs”,内容如下:
public class MyActionFilterAttribute:ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("执行Action之前....<br/>");
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("执行Action之后....<br/>");
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Write("呈现View之前....<br/>");
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Write("呈现View之后....<br/>");
}
}
同时,我们需要在HomeController的Index方法之上添加这个Filter
[Filter.MyActionFilter]
public ActionResult Index()
{
return View();
}
那么我们来运行一下。看一下结果。

发现的确正如我们所猜测的那样。但是这个例子只是给大家说名一下这个过滤器的四个方法分别是在什么之后执行的。
那么我们就可以利用这个可以实现登录验证的操作,比如我们的每个Action执行之前都需要判断用户有没有登录,如果没有登录那么就让他访问对应的Action。所以这个操作应该是在Action之前要判断的。
我们更改一下MyActionFilterAttribute的方法。
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.Cookies["user"] == null || filterContext.HttpContext.Request.Cookies["user"].Value == "")
{
filterContext.Result = new RedirectToRouteResult("default", new System.Web.Routing.RouteValueDictionary(new { controller="Login",action="index"}));
}
filterContext.HttpContext.Response.Write("执行Action之前....<br/>");
}
当检查发送过来的请求,如果没有对应的cookie 则我们跳转到登录页面。运行效果如下:

不知道本章大家有没有明白什么是过滤器呢?在以后的知识介绍中,我们还会使用过滤器,这个比较重要哦!好了,本章就到此结束吧!
一步步学习ASP.NET MVC3 (15)——过滤器的更多相关文章
- 一步步学习ASP.NET MVC3 章节总结
请注明转载地址:http://www.cnblogs.com/arhat 对于<一步步学习ASP.NET MVC3>系列工15章,那么为了方便大家能够快速的预览,老魏在这里为这个系列提供一 ...
- 一步步学习ASP.NET MVC3 (1)——基础知识
请注明转载地址:http://www.cnblogs.com/arhat 首先在这里我想声明一下,这个ASP.NET MVC3系列是我在授课过程中的一些经验,有什么不对的地方,请大家指出,我们共同的学 ...
- 一步步学习ASP.NET MVC3 (3)——Razor(1)
请注明转载地址:http://www.cnblogs.com/arhat 首先这个<一步步学习ASP.NET MVC3>前段时间有些忙,没有顾得上写文章,昨天呢写了3个和ASP.NET的相 ...
- 一步步学习ASP.NET MVC3 (12)——FileResult
请注明转载地址:http://www.cnblogs.com/arhat 忙了两天,本来老魏昨天就应该写出新的文章,但是由于昨天雨夹雪而且加上昨天晚上加了班,到家都没饭吃了,一看时间都9点了,什么饭店 ...
- 一步步学习ASP.NET MVC3 (2)——入门程序
请注明转载地址:http://www.cnblogs.com/arhat 在上一节中,我们只是简单的介绍了什么是MVC及MVC的运行原理.而本节呢,主要来实现下一ASP.NET MVC3的开发流程,并 ...
- 一步步学习ASP.NET MVC3 (14)——Route路由
请注明转载地址:http://www.cnblogs.com/arhat 由于今天是星期六,所以多写几篇,感觉前几天的忙碌没有及时发布文章,趁着周末老魏尽力的多写几篇文章.因为本系列基本上快结束了,所 ...
- 一步步学习ASP.NET MVC3 (5)——View从Action中获得数据
请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们把Razor的模板技术给大家介绍了一下,当然模板中还有其他的知识点,这个以后我们还会继续讲解.本章我们主要讨论 ...
- 一步步学习ASP.NET MVC3 (6)——@helper,@functions
请注明转载地址:http://www.cnblogs.com/arhat 在前一章中,我们讲述了View如何从Action中获得数据,并显示出来,但随着需求的变化,我们可能要对View中显示的数据作出 ...
- 一步步学习ASP.NET MVC3 (7)——Controller,Action,ActionResult
请注明转载地址:http://www.cnblogs.com/arhat 前面几章我们讲解的都是关于View方面的知识,虽然还有很多关于View的知识没有讲,但是没关系,我们在后面使用到的时候在讲解, ...
随机推荐
- c++20道面试题
摘自传智播客论坛 问1:请用简单的语言告诉我C++ 是什么?答:C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛.C++支持多种编程范式 --面向对象编程.泛型编程和过程化编程. 其编程领 ...
- VS版本下载
tfs2012:BVGTF-T7MVR-TP46H-9Q97G-XBXRB http://www.microsoft.com/zh-cn/download/details.aspx?id=30658 ...
- Java阻塞中断和LockSupport
在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? ...
- C# 接口的隐式与显示实现【转】
以前在用到接口时,从来没注意到接口分为隐式实现与显示实现.昨天在浏览博客时看到相关内容,现在根据自己的理解记录一下,方便日后碰到的时候温习温习.通俗的来讲,“显示接口实现”就是使用接口名称作为方法名的 ...
- 关于IO的一些数字
http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/people ...
- 如何让Div层悬浮在Flash Object对象之上(转载)
今天有个用户,门户右上角的倒三角登陆小按钮在他的电脑上无法显示,他用的笔记本屏幕较小,宽度正好显示出页面内容,经查看,门户页眉使用的为flash对象. 大家都知道,如果想让某个图片或者Div层悬浮在别 ...
- Linux find常见用法示例
find命令的参数: pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示系统根目录.-print: find命令将匹配的文件输出到标准输出.-exec: find命令 ...
- SQL Server2008数据库如何改名
未使用的数据库改名比较方便,找到你要更改的数据库,右键选择[重命名]. 2 然后将你想要更改的名字写好,然后点击一下旁边的空白栏. 3 然后你就发现数据库的名称已经改好了. END 使用中的数据库 ...
- 转载---SQL Server XML基础学习之<7>--XML modify() 方法对 XML 数据中插入、更新或删除
/*------------------------------------------------------------------------------+ #| = : = : = : = : ...
- C#之装箱和拆箱
在实际编码过程中,有时候会出现装箱和拆箱操作.下面就类分别认识一下: 需要注意的是,类型转换和这个是不同的.Convert方法并没有发生装箱和拆箱操作,而是类型转换,包括int.parse等等. 装箱 ...