素材巴巴 > 程序开发 >

ASP.Net Core的Filter

程序开发 2023-09-12 23:03:40

文章目录


一、什么是Filter?

  • 所有筛选器一般有两个版本,比如IActionFilterIAsyncActionFilter


  • 二、Exception filter

    当系统中出现未经处理的异常的时候,异常筛选器就会执行

    1. 新建一个API控制器TestController

    2. 在控制器中编写一个会抛异常的方法,代码如下:

      [HttpGet]
       public string Test1()
       {string s = System.IO.File.ReadAllText("D:1.txt");return s;
       }
       
    3. 调用方法Test1后,会出现以下界面
      出现未处理异常

    4. 当系统中出现未处理异常的时候,假设我们需要统一返回给客户端一个如下格式的响应报文:{"code":"500","message":"异常信息"},可以通过一个实现了IAsyncExceptionFilter接口的类来实现,类的代码如下:

      public class MyExceptionFilter : IAsyncExceptionFilter
       {private readonly IWebHostEnvironment webHost;public MyExceptionFilter(IWebHostEnvironment webHost){this.webHost = webHost;}public Task OnExceptionAsync(ExceptionContext context){string message;if (webHost.IsDevelopment()){message = context.Exception.ToString(); //context.Exception 代表异常信息对象}else{message = "服务器端发生未处理异常!";}ObjectResult objectResult = new ObjectResult(new { code = 500, message = message });context.Result = objectResult;  //context.Result的值会被输入给客户端context.ExceptionHandled = true;    //如果赋值为True,则其他的ExceptionFilter不会再执行return Task.CompletedTask;}
       }
       
    5. 全局注册

      builder.Services.Configure(opt =>
       {opt.Filters.Add();
       });
       
    6. 调用方法Test1后,会出现以下界面:

      在这里插入图片描述

    三、Action filter

    1. 实现IAsyncActionFilter接口

    2. 多个Action Filter的链式执行,执行顺序如下:
      Filter执行顺序

    3. 在TestController中插入以下代码:

      [HttpGet]
       public string Test1()
       {Console.WriteLine("开始执行 Test1");string s = System.IO.File.ReadAllText("D:1.txt");return s;
       }[HttpGet]
       public DateTime GetDateTime()
       {Console.WriteLine("开始执行 GetDateTime");return DateTime.Now;
       }
       
    4. 新建一个实现了IAsyncActionFilter接口的类MyActionFilter

      public class MyActionFilter : IAsyncActionFilter
       {public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){Console.WriteLine("MyActionFilter 开始执行..."); //在Action之前执行ActionExecutedContext result = await next(); //在Action之后执行if(result.Exception == null){Console.WriteLine("MyActionFilter 执行成功了!");}else{Console.WriteLine("MyActionFilter 发生异常了!");}}
       }
       
    5. 分别调用两个方法可以看到控制台中显示以下内容:
      -

    四、实现一个自动启用事务的Action Filter

    1. 创建一个类NotTransactionAttribute ,继承自Attribute,且只能标注到方法上

      [AttributeUsage(AttributeTargets.Method)]
       public class NotTransactionAttribute : Attribute
       {
       }
       
    2. 创建一个类TransactionScopeFilter,实现了IAsyncActionFilter接口

      public class TransactionScopeFilter : IAsyncActionFilter
       {public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){//context.ActionDescriptor  当前被执行的Action方法的描述信息ControllerActionDescriptor? controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;bool isTx = false; //是否进行事务控制if (controllerActionDescriptor != null){//查找当前Action方法的Attribute,是否标记了NotTransactionAttribute//如果标记了NotTransactionAttribute,则返回True,就不进行事务控制bool hasNotTransactionAttribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(NotTransactionAttribute), false).Any();isTx = !hasNotTransactionAttribute;}if (isTx){using (TransactionScope ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)){var r = await next();if (r.Exception == null){ts.Complete();}}}else{await next();}}
       }
       

    标签:

    素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。