ASP.NET MVC过滤器的使用

本文深入探讨ASP.NET MVC中的过滤器概念,包括其作用、分类及自定义实现,如日志记录和错误处理。同时,讲解了过滤器接口的重写及执行顺序,帮助读者理解并有效运用过滤器提升应用程序的健壮性和维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

过滤器的简介

为什么要用过滤器

例如在生活中,乘坐火车、地铁、飞机等一般情况下要将行李进行安检,安检的主要作用:1.规范人们的出行行为。2.保证公共秩序的安全

  1. 调用动作方法之前,或方法调用之后执行的一些业务逻辑,比如“检查当前请求是否授权?方法执行后出现错误如何处理?”,本质就是对动作方法的执行过程进行干预,和Java中Struts里面拦截器有类似作用
  2. 提供了一种向控制器行为方法中添加“前行为(Pre-action)和后行为(Post-action)”的方法

过滤器的理解

  1. 在ASP.NET MVC中继承自拔FilterAttribute的类统称为过滤器
  2. 其实Authorize、HandleError、OutputCahce这些类都直接或者间接继承自FilterAttribute类

过滤器的分类

  1. Authorize(授权):该过滤器用来限制进入控制器的行为
  2. HandleError(处理错误):该过滤器用来限定一个行为,这个行为用来处理某个行为方法中跑出来的异常
  3. OutputCahce(缓存):该过滤器用来为行为方法提供输出缓存
  4. 自定义过滤器:开发者自己根据需要创建的过滤器,例如:日志、权限等

过滤器接口

接口类型方法说明
IActionFiltervoid OnActionExecuted void OnActionExecuting在执行动作方法后调用 在执行动作方法前调用
IResultFiltervoid OnResultExecuted void OnResultExecuting在操作结果执行之后调用 在操作结果执行之前调用
IExceptionFiltervoid OnException在发生异常的时候调用
IAuthorizationFiltervoid OnAuthorization在需要授权的时候调用

这些接口在自定义过滤器的时候并非全部继承根据实际需求选择

自定义日志过滤器

条件
自定义过滤器的条件

  1. 实现任意一个或多个过滤器接口
  2. 继承FilterAttribute
    自定义错误日志过滤器
    实现系统发生异常后,将异常信息保存下来,便于追踪错误
/// <summary>
    /// 自定义的错误日志过滤器
    /// </summary>
    public class LogExceptionFilter : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            //定义一个日志文件路径
            string filepath = filterContext.HttpContext.Server.MapPath(@"~/Log/log.txt");
            //写入日志信息
            using (StreamWriter writer=File.AppendText(filepath))
            {
                writer.WriteLine($"时间:{DateTime.Now}");
                writer.WriteLine($"控制器:{filterContext.RouteData.Values["Controller"]}");
                writer.WriteLine($"动作方法:{filterContext.RouteData.Values["Action"]}");
                writer.WriteLine($"异常信息:{filterContext.Exception.Message}");
                writer.WriteLine("----------------------------------------------------------------------------------------------");
            }
        }
    }

创建的过滤器只要是继承了FilterAttribute类,我们创建的对象就是一个特性,使用方式和.NET中提供的常用的特性使用方式一致
在需要添加错误过滤的地方使用

[HttpPost]
        [HandleError(ExceptionType = typeof(System.Exception), View = "Error")]
        [Filters.LogExceptionFilter]
        public ActionResult GetUserInfor(int Id)
        {
            UserServer server = new UserServer();
            UserInfor user = server.GetUserDetail(Id);
            ViewBag.User = user;
            return View();
        }

重写过滤器接口

在“控制器中,可以重写过滤器接口的方法

public class HomeController : Controller
    {
        protected override void OnException(ExceptionContext filterContext)
        {
            //定义一个日志文件路径
            string filepath = filterContext.HttpContext.Server.MapPath(@"~/Log/log.txt");
            //写入日志信息
            using (StreamWriter writer = System.IO.File.AppendText(filepath))
            {
                writer.WriteLine($"时间:{DateTime.Now}");
                writer.WriteLine($"控制器:{filterContext.RouteData.Values["Controller"]}");
                writer.WriteLine($"动作方法:{filterContext.RouteData.Values["Action"]}");
                writer.WriteLine($"异常信息:{filterContext.Exception.Message}");
                writer.WriteLine("----------------------------------------------------------------------------------------------");
            }
        }

重写Controller类所继承的过滤器方法之后则不需要单独给某个行为方法添加特性,默认是对整个控制器内的行为方法进行使用过滤器

  //
    // 摘要:
    //     提供用于响应对 ASP.NET MVC 网站所进行的 HTTP 请求的方法。
    public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer

Controller对象所继承的这些过滤器接口中的方法都可以重写

总结

  1. 过滤器的三种应用小结
    1. 应用到动作方法上:作用于这个动作方法
    2. 应用到控制器上:作用于这个控制中所有的动作方法
    3. 应用到整个程序中:作用于所有动作方法
  2. FilterConfig.cs文件
    1. 作用:注册全局过滤器
    2. 默认:已将错误处理作为全局过滤器
    3. 扩展:可以添加自己定义的过滤器作为全局过滤器

过滤器的执行顺序

  1. 类上的过滤器优先于方法上的过滤器
  2. 按Order属性从小到大执行
    [Filters.ActionFilter(Order =1)]
    [Filters.ExceptionFilter(Order =2)]
  3. 控制器中重写的过滤器接口方法优先执行
  4. 异常过滤器执行顺序错误
    错误过滤器如果要详细到错误的根本原因,这个错误顺序和之前学习try catch异常捕获顺序要一样,都是从小的错误到大的错误进行顺序
    例如:针对数据库查询等做异常,首先先捕获SqlException异常,如果这个异常捕获不到在进行Exception
        [HandleError(ExceptionType = typeof(SqlException), View = "Error")]
        [HandleError(ExceptionType = typeof(System.Exception), View = "Error")]
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值