zoukankan      html  css  js  c++  java
  • C# ASP.NET MVC中Filter过滤器的使用 通过注册到Global.asax注册为全局 过滤所有action

    原文链接 https://blog.csdn.net/pan_junbiao/article/details/84523935

    比如 ActionFilter中ActionExecutingContext filterContext可以拿到请求中的上下文。可以拿到请求action的名字controller的名字。和要请求的action 的上的标签等。filterContext.Result 可以给响应复制。截断请求,从而执行当前返回结果。

    MVC Filter是典型的AOP(面向切面编程)应用,在ASP.NET MVC中的4个过滤器类型,如下:

    过滤器类型 接口 默认实现 描述
    Action IActionFilter ActionFilterAttribute 在动作方法之前及之后运行
    Result IResultFilter ActionFilterAttribute 在动作结果被执行之前和之后运行
    AuthorizationFilter IAuthorizationFilter AuthorizeAttribute 首先运行,在任何其它过滤器或动作方法之前
    Exception IExceptionFilter HandleErrorAttribute 只在另一个过滤器、动作方法、动作结果弹出异常时运行

    但是默认实现它们的过滤器只有三种,分别是ActionFilter(方法),Authorize(授权),HandleError(错误处理)。

    1、Action过滤器

    在ASP.NET MVC中创建MvcApp项目,创建文件夹Filter,然后新建类MyActionFilterAttribute(为了遵循默认的约定,名称以Attribute结尾),继承自ActionFilterAttribute类。ActionFilterAttribute类有如下4个方法。

    1. using System;
    2. namespace System.Web.Mvc
    3. {
    4. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    5. public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
    6. {
    7. protected ActionFilterAttribute();
    8. public virtual void OnActionExecuted(ActionExecutedContext filterContext);
    9. public virtual void OnActionExecuting(ActionExecutingContext filterContext);
    10. public virtual void OnResultExecuted(ResultExecutedContext filterContext);
    11. public virtual void OnResultExecuting(ResultExecutingContext filterContext);
    12. }
    13. }

    实现MyActionFilterAttribute类:

    1. using System;
    2. using System.Web.Mvc;
    3. namespace MvcApp.Filter
    4. {
    5. public class MyActionFilterAttribute : ActionFilterAttribute
    6. {
    7. public override void OnActionExecuting(ActionExecutingContext filterContext)
    8. {
    9. //1、获取请求的类名和方法名
    10. string strController = filterContext.RouteData.Values["controller"].ToString();
    11. string strAction = filterContext.RouteData.Values["action"].ToString();
    12. //2、用另一种方式获取请求的类名和方法名
    13. string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    14. string strAction2 = filterContext.ActionDescriptor.ActionName;
    15. filterContext.HttpContext.Response.Write("控制器:" + strController + "<br/>");
    16. filterContext.HttpContext.Response.Write("控制器:" + strController2 + "<br/>");
    17. filterContext.HttpContext.Response.Write("Action:" + strAction + "<br/>");
    18. filterContext.HttpContext.Response.Write("Action:" + strAction2 + "<br/>");
    19. filterContext.HttpContext.Response.Write("Action执行前:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
    20. base.OnActionExecuting(filterContext);
    21. }
    22. public override void OnActionExecuted(ActionExecutedContext filterContext)
    23. {
    24. filterContext.HttpContext.Response.Write("Action执行后:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
    25. base.OnActionExecuted(filterContext);
    26. }
    27. }
    28. }

    对于过滤器,我们可以把它们加在3个地方,一个是控制器上面(控制器下面的所有Action),一个是Action上面(指定标识的Action),另一个就是全局位置(所有控制器中的Action)。这里只演示在Action上面和Home控制器中:

    1. [MyActionFilter]
    2. public ActionResult Index()
    3. {
    4. return View();
    5. }

    2、Result过滤器

    新建MyResultFilterAttribute类,继承ActionFilterAttribute:

    1. using System;
    2. using System.Web.Mvc;
    3. namespace MvcApp.Filter
    4. {
    5. public class MyResultFilterAttribute : ActionFilterAttribute
    6. {
    7. /// <summary>
    8. /// 加载“视图”前执行
    9. /// </summary>
    10. /// <param name="filterContext"></param>
    11. public override void OnResultExecuting(ResultExecutingContext filterContext)
    12. {
    13. filterContext.HttpContext.Response.Write("加载视图前执行 OnResultExecuting" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
    14. base.OnResultExecuting(filterContext);
    15. }
    16. /// <summary>
    17. /// 加载“视图”后执行
    18. /// </summary>
    19. /// <param name="filterContext"></param>
    20. public override void OnResultExecuted(ResultExecutedContext filterContext)
    21. {
    22. filterContext.HttpContext.Response.Write("加载视图后执行 OnResultExecuted" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");
    23. base.OnResultExecuted(filterContext);
    24. }
    25. }
    26. }

    这里把MyResultFilter过滤器加在控制器上面,相当于给Home控制器中的所有的Action方法添加了MyResultFilter过滤器。

    1. using MvcApp.Filter;
    2. using System.Web.Mvc;
    3. namespace MvcApp.Controllers
    4. {
    5. [MyResultFilter]
    6. public class HomeController : Controller
    7. {
    8. [MyActionFilter]
    9. public ActionResult Index()
    10. {
    11. return View();
    12. }
    13. }
    14. }

    3、AuthorizeAttribute过滤器

    创建MyAuthorizeAttribute类,继承AuthorizeAttribute类:

    1. using System.Web.Mvc;
    2. namespace MvcApp.Filter
    3. {
    4. /// <summary>
    5. /// 授权过滤器
    6. /// </summary>
    7. public class MyAuthorizeAttribute : AuthorizeAttribute
    8. {
    9. public override void OnAuthorization(AuthorizationContext filterContext)
    10. {
    11. filterContext.HttpContext.Response.Write("OnAuthorization<br/>");
    12. //注释掉父类方法,因为父类里的OnAuthorization方法会调用ASP.NET的授权验证机制
    13. //base.OnAuthorization(filterContext);
    14. }
    15. }
    16. }

    在控制器Home中的Index上添加MyAuthorize过滤器:

    1. [MyAuthorize]
    2. [MyActionFilter]
    3. public ActionResult Index()
    4. {
    5. return View();
    6. }

    通常Authorize过滤器也是在全局过滤器上面的,主要用来做登录验证或者权限验证,在App_Start目录下的FilterConfig类的RegisterGlobalFilters方法中添加:

    1. public class FilterConfig
    2. {
    3. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    4. {
    5. //filters.Add(new HandleErrorAttribute());
    6. //添加全局授权过滤器
    7. filters.Add(new MyAuthorizeAttribute());
    8. }
    9. }

    在全局中注册过滤器,则所有控制器的所有行为(Action)都会执行这个过滤器。

    运行结果,如下图:

    4、Exception过滤器

    创建MyHandleErrorAttribute类,继承HandleErrorAttribute类:

    1. using System;
    2. using System.Web.Mvc;
    3. namespace MvcApp.Filter
    4. {
    5. /// <summary>
    6. /// 异常处理过滤器
    7. /// </summary>
    8. public class MyHandleErrorAttribute : HandleErrorAttribute
    9. {
    10. public override void OnException(ExceptionContext filterContext)
    11. {
    12. //1、获取异常对象
    13. Exception ex = filterContext.Exception;
    14. //2、记录异常日志
    15. //3、重定向友好页面
    16. filterContext.Result = new RedirectResult("~/error.html");
    17. //4、标记异常已经处理完毕
    18. filterContext.ExceptionHandled = true;
    19. base.OnException(filterContext);
    20. }
    21. }
    22. }

    在Action上面添加MyHandleError过滤器:

    1. [MyHandleError]
    2. public ActionResult GetErr()
    3. {
    4. int a = 0;
    5. int b = 1 / a;
    6. return View();
    7. }

    创建异常错误友好提示页面error.html。

    1. <body>
    2. 自定义错误页面
    3. </body>

    运行会自动跳转到error.html页面。

    如果页面没有跳转,就需要去Web.config配置文件中的<system.web>节点下面添加如下配置节点,开启自定义错误:

    <customErrors mode="On"></customErrors>

    通常这样的异常处理是放在全局过滤器上面的,只要任意Action方法报错就会执行MyHandleError过滤器中的代码。

    修改App_Start目录下面的FilterConfig类:

    1. public class FilterConfig
    2. {
    3. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    4. {
    5. //filters.Add(new HandleErrorAttribute());
    6. //添加全局授权过滤器
    7. filters.Add(new MyAuthorizeAttribute());
    8. //添加全局异常处理过滤器
    9. filters.Add(new MyHandleErrorAttribute());
    10. }
    11. }

    Global.asax下的代码:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Web.Mvc;
    6. using System.Web.Optimization;
    7. using System.Web.Routing;
    8. namespace MvcApp
    9. {
    10. public class MvcApplication : System.Web.HttpApplication
    11. {
    12. protected void Application_Start()
    13. {
    14. AreaRegistration.RegisterAllAreas();
    15. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    16. RouteConfig.RegisterRoutes(RouteTable.Routes);
    17. BundleConfig.RegisterBundles(BundleTable.Bundles);
    18. }
    19. }
    20. }
  • 相关阅读:
    Java学习——文件和IO流
    Java多线程——ThreadLocal类的原理和使用
    Java多线程——线程八锁案例分析
    Django 模版语法 一
    Django 命令行调用模版渲染
    Django 使用 locals() 函数
    Django 加载 app 中的urls
    Django 传递额外参数及 URL别名
    Django 无名参数与有名参数
    Django 项目中添加静态文件夹
  • 原文地址:https://www.cnblogs.com/sunny3158/p/11683554.html
Copyright © 2011-2022 走看看