相信对权限过滤大家伙都不陌生

用户要访问一个页面时

先对其权限进行判断并进行相应的处理动作

在webform中

最直接也是最原始的办法就是

在page_load事件中所有代码之前

先执行一个权限判断的方法

至于其专业的权限机制这里不做讨论

想要了解的同学可以自行google之

或者点击进入:

webform专业的权限验证机制

那么mvc中是如何实现权限验证的?

据我们所知

mvc中是根据路由配置来请求控制器类中的一个方法

并没有webform中的page_load方法

难道我们要在每个action方法中都调用一个权限判断的方法吗?

很明显不可能= =

懒惰的程序员们怎么可能允许这种情况发生

其实在mvc框架中

为程序员提供了一种过滤器机制

通过过滤器

我们可以随心所欲的控制访问权限

那么接下来

教育科学频道--走近科学带你进入过滤器的内心世界~~

首先,我们可以自己添加一个过滤器

添加一个类,名为MyFilter1Attribute

并继承自ActionFilterAttribute类(注意,这里的ActionFilterAttribute的命名空间是System.Web.Mvc不要引用错了~)

现在这个MyFilter1Attribute就是一个过滤器类了

因为继承自ActionFilterAttribute类

所以我们自己添加的MyFilter1Attribute就拥有了某些过滤方法

我们对ActionFilterAttributeF12转到定义看一看里面有什么东西

可以看到,这个ActionFilterAttribute是一个特性类(这就是人家为什么以Attribute结尾啦~)

并且实现了两个很重要的接口IActionFilter,IResultFilter

我们在转到定义看一下这两个接口中有什么

可以看到

这两个接口中各自定义了两个方法,而ActionFilterAttribute既然实现了它们,那么ActionFilterAttribute自然也会拥有这四个方法

那么这四个方法是什么呢?

马上揭晓~

前面我们说到过,ActionFilterAttribute其实是一个特性类

什么是特性类?

就比如之前进实体验证的时候,为实体的字段贴上的标签

那个标签就是一个特性类

也就是说

特性类可以通过贴标签的形式来使用

而我们自己添加的MyFilter1Attribute也是一个特性类

这有什么用吗?

等下你就知道了~

现在先在MyFilter1Attribute中重写OnActionExecuting方法

其实我们可以从这个方法的名字上大概推出这个方法是做什么的了

没错,该方法会在action方法执行之前调用

反之IActionFilter中的另一个方法--OnActionExecuted就是在action方法执行完毕之后调用

口说无凭

下面上证据:

  1. public class MyFilter1Attribute:ActionFilterAttribute
  2. {
  3. //该方法会在action方法执行之前调用
  4. public override void OnActionExecuting(ActionExecutingContext filterContext)
  5. {
  6. filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法调用钱执行<br/>");
  7. base.OnActionExecuting(filterContext);
  8. }
  9.  
  10. //该方法会在action方法执行之后调用
  11. public override void OnActionExecuted(ActionExecutedContext filterContext)
  12. {
  13. filterContext.HttpContext.Response.Write("我是OnActionExecuted,我在action方法调用后执行<br/>");
  14. base.OnActionExecuted(filterContext);
  15. }
  16.  
  17. }

在Home控制器中添加一个action方法

  1. [MyFilter1]
  2. public void FilterTest()
  3. {
  4. Response.Write("我是action方法,在这里执行了~~</br>");
  5. }

这时候看到了吗?

要在一个action方法中使用一个过滤器

只要在该方法上贴一个过滤器的标签就ok~ 

生成运行,结果如下:

强有力的证明~

但是呢,有时候我们会有这样的一需求:

在过滤器中当遇到了贴了某某标签的action方法就跳过不进行验证

这怎么办呢?

可以通过filterContext的ActionDescriptor属性类完成这易操作

ActionDescriptor顾名思义,action方法的描述着

在ActionDescriptor中我们可以拿到相应的action方法信息,甚至还可以拿到一个控制器描述着ControllerDescriptor

代码如下:

  1. //该方法会在action方法执行之前调用
  2. public override void OnActionExecuting(ActionExecutingContext filterContext)
  3. {
  4. filterContext.HttpContext.Response.Write("我是OnActionExecuting,我在action方法调用前执行<br/>");
  5. //判断该action方法时候有贴上MyFilter1Attribute标签
  6. if (filterContext.ActionDescriptor.IsDefined(typeof (MyFilter1Attribute),false))
  7. {
  8. //如果有,为该action方法直接返回ContentResult,则该action方法在这里就有了返回值,相当于在这里就结束了,不会在去执行之后的方法,如:OnActionExecuted等
  9. filterContext.Result = new ContentResult();
  10. }
  11. base.OnActionExecuting(filterContext);
  12. }

结果如图:

可以看到,action方法中和OnActionExecuted中的Response.Write都没有被执行,也就是说,该action方法被跳过了

之前我们使用的是IActionFilter接口中的方法

接下来介绍IResultFilter接口方法

  1. //在action方法返回结果之后执行
  2. public override void OnResultExecuting(ResultExecutingContext filterContext)
  3. {
  4. filterContext.HttpContext.Response.Write("我是OnActionExecuted,我action方法返回结果之前执行<br/>");
  5. base.OnResultExecuting(filterContext);
  6. }
  7.  
  8. //在action方法返回结果之前前执行
  9. public override void OnResultExecuted(ResultExecutedContext filterContext)
  10. {
  11. filterContext.HttpContext.Response.Write("我是OnResultExecuted,我在action方法返回结果之后执行<br/>");
  12. base.OnResultExecuted(filterContext);
  13. }

IResultFilter中同样也有两个方法

我们将FilterTest改为下面代码:

  1. [MyFilter1]
  2. public ActionResult FilterTest()
  3. {
  4. Response.Write("我是action方法的Response.Write,在这里执行了~~</br>");
  5. return View();
  6. }

并添加视图如下:

  1. <body>
  2. <div>
  3. 我是FilterTest的视图,在这里执行action方法~~
  4. </div>
  5. </body>

生成并运行,结果图:

可以看到,IResultFilter接口中的方法和IActionFilter方法的区别就是执行位置不一样

但是呢,mvc框架中还有一个过滤器

他就是权限过滤器AuthorizeAttribute

该过滤器在所有action方法过滤器之前执行,也就是说,提供了一个可以超前验证的方法

我们在添加一个新的过滤器类,并继承自AuthorizeAttribute

重写其OnAuthorization方法如下:

这里需要注意,把基类的OnAuthorization方法去掉,因为我们并不需要,而且留着可能会出现一些错误异常

  1. public class MyFilter2Attribute:AuthorizeAttribute
  2. {
  3. //在所有action方法过滤器之前执行
  4. public override void OnAuthorization(AuthorizationContext filterContext)
  5. {
  6. filterContext.HttpContext.Response.Write("我是OnAuthorization,在所有action方法过滤器之前执行<br/>");
  7. //base.OnAuthorization(filterContext);
  8. }
  9. }
  1. [MyFilter1]
  2. [MyFilter2]
  3. public ActionResult FilterTest()
  4. {
  5. Response.Write("我是action方法的Response.Write,在这里执行了~~</br>");
  6. return View();
  7. }

为FilterTest方法在贴上MyFilter2标签

运行:

有图有证据~

如此一来

我们就可以根据需要选择合适的方法进行权限验证

但是这时候又有问题了

什么问题呢?

这个特性是贴在action方法上面的

如果我控制器中所有的action方法都要进行验证怎么办?

难道每个action方法都贴一遍吗?

如果我程序中的所有控制器中的所有action方法都需要验证呢?

放心~

懒惰的程序员们是不会去做这种傻事的~

如果一个控制器中的所有方法都需要验证

那么我们可以再控制器类上统一贴上标签,如下:

这样一来该控制器中的所有action方法都会进行验证

那么如果每个控制器类都要验证呢?

这个时候我们就需要打开App_Start文件夹了

看到一个FilterConfig类了吗

双击打开FilterConfig.cs

我们可以再这里进行添加全局的过滤器,比如:

最后我们在介绍一个异常处理的过滤器

添加一个过滤器类,并继承自HandleErrorAttribute

  1. public class MyFilter3Attribute:HandleErrorAttribute
  2. {
  3. //在程序中任何地方出现异常都会执行
  4. public override void OnException(ExceptionContext filterContext)
  5. {
  6. //获取异常对象
  7. Exception ex = filterContext.Exception;
  8. //记录错误日志
  9. //导向友好错误界面
  10. filterContext.Result = new RedirectResult("/Home/Index");
  11. //重要!!告诉系统异常已处理!!如果没有这个步骤,系统还是会按照正常的异常处理流程走
  12. filterContext.ExceptionHandled = true;
  13. //base.OnException(filterContext);
  14. }
  15. }

注意,这里基类的OnException也是不需要的

那么异常处理的过滤器要放在哪里呢?

肯定是全局的呀~

  1. filters.Add(new MyFilter3Attribute());

ok,搞定~

不信你运行看看~

asp.net mvc的入门学习到此就全部结束了~

期待着下一次的进步!



ASP.NET MVC学习---(九)权限过滤机制(完结篇)的更多相关文章

  1. ASP.NET MVC学习(一)之路由篇Route

    什么是路由 通过[路由]配置,路由可以规定URL的特殊格式,使其达到特殊效果. 在ASP.NET MVC框架中,通过路由配置URL,使用户的URL请求可以映射到Controller下的action方法 ...

  2. ASP.NET MVC学习目录

    一.ASP.NET MVC原理详解 1.了解MVC架构模式 3.学习ASP.NET MVC的必备语言知识 4.MVC中的razor语法详解 5.ASP.NET MVC路由系统机制详细讲解 6.ASP. ...

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

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

  4. ASP.NET MVC学习系列(二)-WebAPI请求

    继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的get和post请求,我们在Web API中要如何来处理. 这里我使用Jquery 来发起异步请求实现 ...

  5. ASP.NET MVC学习系列(二)-WebAPI请求(转)

    转自:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...

  6. (转)ASP.NET MVC 学习第一天

    天道酬勤0322   博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅  | 管理 随笔:10 文章:0 评论:9 引用:0 ASP.NET MVC 学习第一天 今天开始第一天学习as ...

  7. ASP.NET MVC学习之控制器篇扩展性

    原文:ASP.NET MVC学习之控制器篇扩展性 一.前言 在之前的一篇随笔中已经讲述过控制器,而今天的随笔是作为之前的扩展. 二.正文 1.自定义动作方法 相信大家在开发过程一定会遇到动作方法的重名 ...

  8. ASP.NET MVC学习笔记-----Filter

    ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...

  9. Asp.Net MVC学习总结之过滤器详解(转载)

    来源:http://www.php.cn/csharp-article-359736.html   一.过滤器简介 1.1.理解什么是过滤器 1.过滤器(Filters)就是向请求处理管道中注入额外的 ...

  10. [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参

    [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...

随机推荐

  1. 《c程序设计语言》读书笔记-4.12-递归整数转字符串

    #include <stdio.h> #include <math.h> #include <stdlib.h> void itoa_num(int n, char ...

  2. BZOJ 2199: [Usaco2011 Jan]奶牛议会

    2199: [Usaco2011 Jan]奶牛议会 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 375  Solved: 241[Submit][S ...

  3. mysql 游标的嵌套使用示例

    BEGIN DECLARE trainee_no_value BIGINT (20); -- 学员编号 DECLARE pay_no_value BIGINT (20); -- 交费序号 DECLAR ...

  4. 【Tomcat】一台电脑上运行多个tomcat

    效果: 1.首先需要安装Tomcat7,Tomcat8. Tomcat7: Tomcat8: 2.添加两个环境变量,添加CATALINA_HOME1和CATALINA_BASE1指向E:\tomcat ...

  5. 计算器的改良(纯字符串)o1

    原题传送门 这题比较水,就是细节..多了点. 首先字符串要处理好(废话..) 基础不行的话要多去看看书.. 然后捏,这题主要就是几个判断: 当我们读字符,如果读到运算符号,那么就要停下来,把之前的常数 ...

  6. eclipse easy shell plugin

    svn checkout svn://svn.code.sf.net/p/pluginbox/code/trunk pluginbox-code   Eclipse中Easy Shell插件配置Pow ...

  7. 《Linux命令行与shell脚本编程大全 第3版》高级Shell脚本编程---47

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  8. glxgears刷新只有60FPS解决办法

    问题原因在于屏幕的垂直同步刷新率的限制,解决办法是关闭垂直同步刷新. 编辑~/.drirc <driconf> <device screen=" driver=" ...

  9. Appium+python自动化15-在Mac上环境搭建【转载】

    前言 mac上搭建appium+python的环境还是有点复杂的,需要准备的软件 1.nodejs 2.npm 3.cnpm 4.appium 5.pip 6.Appium-Python-Client ...

  10. PHP成生若干位防伪码的方法

    public static function createCode($length =16) { $arr = array_merge(range(0, 9), range('a', 'z')); / ...