AuthorizeFilter筛选器

在Action的执行中包括两个重要的部分,一个是Action方法本身逻辑代码的执行,第二个就是Action方法的筛选器的执行。

MVC4中筛选器都是以AOP(面向方面编程)的方式来设计的,通过对Action方法上标注相应的Attribute标签来实现。MVC4提供了四种筛选器,分别为:AuthorizationFilter、ActionFilter、ExceptionFilter和ResultFilter,他们分别对应了四个筛选器接口IAuthorizationFilter、IActionFilter、IExceptionFilter和IResultFilter。

这四种筛选器都有派生于一个公共的类FilterAttribute,该类指定了筛选器的执行顺序Order和是否允许多个应用AllowedMultiple。这四种筛选器默认的执行顺序为最先进行授权筛选,最后进行异常处理,中间则是ActionFilter和ResultedFilter。

下面是抽象类FilterAttribute的类图

下面我们来具体列举一下各个筛选器的作用和实现

从字面上我们就能看出这是对Controller或Action方法授权的筛选器,即在Controller或Action方法执行前,首先会先执行该筛选器,若通过,才会继续执行。下面是此筛选器的简单类图

AuthorizeAttribute为最终授权筛选器的实现者,它实现了IAuthorizationFilter接口和FilterAttribute抽象类,接口中的OnAuthorization(AuthorizationContext filterContext)方法是最终验证授权的逻辑(其中AuthorizationContext是继承了ControllerContext类)

[csharp] view plain copy
  1. protected virtual bool AuthorizeCore(HttpContextBase httpContext)
  2. {
  3. if (httpContext == null)
  4. {
  5. throw new ArgumentNullException("httpContext");
  6. }
  7. IPrincipal user = httpContext.User;
  8. if (!user.Identity.IsAuthenticated)
  9. {
  10. return false;
  11. }
  12. if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
  13. {
  14. return false;
  15. }
  16. if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
  17. {
  18. return false;
  19. }
  20. return true;
  21. }

AuthorizeCore方法是最终OnAuthorization()方法调用的最终逻辑,从代码可以看出,当同时指定了users和roles时,两者只有同时满足条件时才可以验证授权通过。如

[csharp] view plain copy
  1. [Authorize(Users="zhangsan", Roles="Admin")]
  2. public ActionResult ActionMethod()
  3. {
  4. }

则只有用户zhangsan,且用户属于Admin角色时才能验证授权通过。

若验证不通过时,OnAuthorization方法内部会调用HandleUnauthorizedRequest

虚方法进行处理,代码如下:

[csharp] view plain copy
  1. protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
  2. {
  3. // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
  4. filterContext.Result = new HttpUnauthorizedResult();
  5. }

该方法设置了参数上下文中ActionResult的值,用于供View展示。

我们可以自定义Authorize筛选器,由于OnAthurization()、AuthorizeCore()和HandleUnauthorizedRequest()方法都是虚方法,我们自定义的Authorize筛选器只需要继承AuthorizeAttribute类,重写以上三种方法,这样就可以自定义自己的验证规则和验证失败时的处理逻辑了。

IAuthorizationFilter还有其他类型的实现类,如RequireHttpsAttribute、ValidateInputAttribute都是实现了OnAuthorization()方法,来完成各自筛选器处理的。

ExceptionFilter过滤器

该筛选器是在系统出现异常时触发,可以对抛出的异常进行处理。所有的ExceptionFilter筛选器都是实现自IExceptionFilter接口

[csharp] view plain copy
  1. public interface IExceptionFilter
  2. {
  3. void OnException(ExceptionContext filterContext);
  4. }

实现OnException方法来实现对异常的自定义处理

MVC4中实现了默认的异常处理机制,源码如下

[csharp] view plain copy
  1. public virtual void OnException(ExceptionContext filterContext)
  2. {
  3. if (filterContext == null)
  4. {
  5. throw new ArgumentNullException("filterContext");
  6. }
  7. if (filterContext.IsChildAction)
  8. {
  9. return;
  10. }
  11. // If custom errors are disabled, we need to let the normal ASP.NET exception handler
  12. // execute so that the user can see useful debugging information.
  13. if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
  14. {
  15. return;
  16. }
  17. Exception exception = filterContext.Exception;
  18. // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
  19. // ignore it.
  20. if (new HttpException(null, exception).GetHttpCode() != 500)
  21. {
  22. return;
  23. }
  24. if (!ExceptionType.IsInstanceOfType(exception))
  25. {
  26. return;
  27. }
  28. string controllerName = (string)filterContext.RouteData.Values["controller"];
  29. string actionName = (string)filterContext.RouteData.Values["action"];
  30. HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
  31. filterContext.Result = new ViewResult
  32. {
  33. ViewName = View,
  34. MasterName = Master,
  35. ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
  36. TempData = filterContext.Controller.TempData
  37. };
  38. filterContext.ExceptionHandled = true;
  39. filterContext.HttpContext.Response.Clear();
  40. filterContext.HttpContext.Response.StatusCode = 500;
  41. // Certain versions of IIS will sometimes use their own error page when
  42. // they detect a server error. Setting this property indicates that we
  43. // want it to try to render ASP.NET MVC's error page instead.
  44. filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
  45. }
Application_Start中将HandleErrorAttribute添加到全局筛选器GlobalFilterCollection中,系统即会对异常进行对应的处理。
我们现在实现一个自定义的异常处理筛选器,在处理完后记录异常信息至日志文件中  
[csharp] view plain copy
  1. public class MyExceptionHandleAttribute : HandleErrorAttribute
  2. {
  3. public MyExceptionHandleAttribute()
  4. : base()
  5. {
  6. }
  7. public void OnException(ExceptionContext filterContext)
  8. {
  9. base.OnException(filterContext);
  10. //记录日志
  11. log.Info(filterContext.Exception);
  12. }
  13. }
在GlobalFilterCollection添加MyExceptionHandleAttribute 即可使用自定义的异常筛选器来处理

ActionFilter筛选器

ActionFilter筛选器是在Action方法执行前后会触发,主要用于在Action执行前后处理一些相应的逻辑。ActionFilter的筛选器都继承于ActionFilterAttribute抽象类,而它实现了IActionFilter、IResultFilter和FilterAttribute类,结构如下

因此自定义ActionFilter筛选器只要继承ActionFilterAttribute,实现其中的方法即可。

我们来举一个简单的例子,获取Action方法的执行时长,代码如下

[csharp] view plain copy
  1. public class DefaultController : Controller
  2. {
  3. [ActionExecTimeSpan]
  4. public ActionResult DoWork()
  5. {
  6. return View();
  7. }
  8. }
  9. public class ActionExecTimeSpanAttribute : ActionFilterAttribute
  10. {
  11. private const string executeActionTimeKey = "ActionExecBegin";
  12. public override void OnActionExecuting(ActionExecutingContext filterContext)
  13. {
  14. base.OnActionExecuting(filterContext);
  15. //记录开始执行时间
  16. filterContext.HttpContext.Items[executeActionTimeKey] = DateTime.Now;
  17. }
  18. public override void OnActionExecuted(ActionExecutedContext filterContext)
  19. {
  20. //计算执行时间,并记录日志
  21. if (filterContext.HttpContext.Items.Contains(executeActionTimeKey))
  22. {
  23. DateTime endTime = DateTime.Now;
  24. DateTime beginTime = Convert.ToDateTime(filterContext.HttpContext.Items[executeActionTimeKey]);
  25. TimeSpan span = endTime - beginTime;
  26. double execTimeSpan = span.TotalMilliseconds;
  27. log.Info(execTimeSpan + "毫秒");
  28. }
  29. //
  30. base.OnActionExecuted(filterContext);
  31. }
  32. }

ResultFilter筛选器

ResultFilter筛选器是对Action方法返回的Result结果进行执行时触发的。它也分执行前和执行后两个段执行

所有的ResultFilter都实现了IResultFilter接口和FilterAttribute类,看一下接口定义

[csharp] view plain copy
  1. public interface IResultFilter
  2. {
  3. void OnResultExecuting(ResultExecutingContext filterContext);
  4. void OnResultExecuted(ResultExecutedContext filterContext);
  5. }
其中OnResultExecuting和OnResultExecuted方法分别是在Result执行前、后(页面展示内容生成前、后)触发。
使用ResultFilter筛选器最典型的应用就是页面静态化,我们以后在其他文章中在对此进行详细讲解

学习什么时候都不晚,从现在起我们一起

转载于:https://www.cnblogs.com/jjg0519/p/8759221.html

MVC四大筛选器—ActionFilterResultedFilter相关推荐

  1. Asp.Net MVC 页面代码压缩筛选器-自定义删除无效内容

    Asp.Net MVC 页面代码压缩筛选器 首先定义以下筛选器,用于代码压缩. /*页面压缩 筛选器*/public class WhiteSpaceFilter : Stream{private S ...

  2. ASP.NET Web API 安全筛选器

    原文:https://msdn.microsoft.com/zh-cn/magazine/dn781361.aspx 身份验证和授权是应用程序安全的基础.身份验证通过验证提供的凭据来确定用户身份,而授 ...

  3. tableau获取筛选器值_Tableau操作筛选器(Tableau Action Filters)

    Tableau操作筛选器(Tableau Action Filters) 我在Tableau中有三张纸. Sheet1是我想要进行过滤的主工作表. 我的想法是,如果用户点击那里的价值,那么会显示包含相 ...

  4. 如何更新 Exchange2003 SP2 中的智能邮件筛选器版本

    概要 本文介绍了可用于维护 Microsoft Exchange 2003 Service Pack 2 (SP2) 所附带的智能邮件筛选器版本 2 的更新过程. 在每月的第一个和第三个星期三,将通过 ...

  5. c#学习之基础篇(filter 筛选器)

    提供的筛选器字符串无效.筛选器字符串必须包含筛选器的说明,后跟竖线(|)和筛选模式.不同筛选选项的字符串还必须以竖线分隔.例如:"文本文件(*.txt)|*.txt|所有文件(*.*)|*. ...

  6. 通过BCS对象模型使用筛选器

    在上一篇博文中,我们介绍了如何使用SharePoint服务器上的业务连接服务对象模型连接到BCS服务元数据存储,来获取一个企业核心业务系统对象.外部内容类型及其方法,以及如何执行一个外部内容类型的方法 ...

  7. desc excel 公式_Excel小技巧之Power Pivot Generate函数、高级DAX函数与常用筛选器函数...

    一.使用Generate函数创建信息叠加表 [目标:将姓名与月份组合,生成每个月份均有对应姓名对应的表格][基本思路:pivot中创建度量值,利用DAX函数创建链接回表后在EXCEL释放]       ...

  8. jQuery 选择器和筛选器

    1. jQuery 1. 选择器 $("") 1. 基本选择器 1. ID --> $("#d1") 2. 标签名 --> $("p&qu ...

  9. Spring MVC使用拦截器实现权限控制

    1.首先准备对应的架包 2.看看项目的架构 3.基本的web.xml文件 <!--?xml version="1.0" encoding="UTF-8"? ...

  10. 设置IE安全并打开自动仿冒网站筛选器和IE安全设置

    1.1.1 设置IE安全并打开自动仿冒网站筛选器 什么是仿冒? 联机仿冒(phishing 发音为 fishing)是通过欺诈电子邮件或网站来诱使计算机用户透露个人信息或财务信息的伎俩.常见联机仿冒骗 ...

最新文章

  1. OpenCV读写视频文件解析(二)
  2. gitlab报错 fatal: index-pack failed error: RPC failed; result=18, HTTP code = 200解决方案
  3. 重写selenium 的 click()操作,使得脚本更稳定
  4. 大连理工大学c语言第三次上机作业答案,大连理工大学软件学院C语言上机第五六章课后题...
  5. SoaBox 1.1.6 GA 发布,SOA 模拟环境
  6. QT5 QSqlQuery的SELECT INSERT UPDATE DELETE命令用法
  7. 1.8 编程基础之多维数组 09 矩阵乘法 6分 python
  8. 程序员和美工是否可共存?
  9. Java实现 俄罗斯方块(简陋版)
  10. sqlplus连接Oracle 11g 数据库
  11. 2021哈工程计算机考研科目,2021考研大纲:哈尔滨工程大学计算机专业基础综合2021年硕士研究生自命题考试大纲...
  12. 体脂率计算原理以及python实现(一目了然)
  13. ubuntu打开网易云音乐
  14. python 开发管理软件 ERP
  15. 锐龙r75800u参数 r7 5800u怎么样
  16. 这-96到底是个什么东西?
  17. 测试工程师-入门指南
  18. 【计算机网络】Socket编程
  19. 使用qt实现多线程编程
  20. LINUX JDK 安装与环境变量设置

热门文章

  1. 安卓绿色联盟安全标准1.0到2.0,让用户隐私更安全
  2. 使用drawBitmapMesh扭曲图像
  3. 日常---区域赛临近
  4. 软件工程--结对第二次作业
  5. 在源文件(.c)和头文件(.h)中声明和定义的区别——C语言
  6. Laravel Request 和 Laravel Input 常用操作方法
  7. Python 全栈开发二 python基础 字符串 字典 集合
  8. Thread_多线程
  9. Activity的任务栈Task以及启动模式与Intent的Flag详解
  10. 20行代码实现网页图片抓取。(待完善