.Net Core 教程 Part4 – (38)(39)(40)(41)过滤器 Filter

Part4 – (38) ExceptionFilter 异常筛选器

什么是Filter

1、切面编程机制,在ASP.NET Core特定的位置执行我们自定义的代码。

  • 例如记录日志,检查用户权限,尽量不影响业务逻辑代码。

2、ASP.NET Core中的Filter的五种类型:Authorization filter、Resource filter、Action filter、Exception filter、Result filter。这里重点讲解Exception filter和Action filter。

3、所有筛选器一般有同步和异步两个版本,比如IActionFilter、IAsyncActionFilter接口。

Exception Filter

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

实现

1、当系统中出现未处理异常的时候,我们需要统一给客户端返回如下格式的响应报文:{“code”:”500”,”message”:”异常信息”}。

对于开发环境中message是异常堆栈,对于其他环境message用一个general的报错信息。

2、实现IAsyncExceptionFilter接口。注入IHostEnvironment 得知运行环境。

.Net Core 教程 Part4 – (38)(39)(40)(41)过滤器 Filter
500错误 在开发环境中显示了堆栈异常

这里我们一共设计两个异常捕获,一个处理结果,另一个记录日志,如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Part4_38
{
    public class MyExceptionFilter : IAsyncExceptionFilter
    {
        private readonly IWebHostEnvironment hostEnv;

        public MyExceptionFilter(IWebHostEnvironment hostEnv)
        {
            this.hostEnv = hostEnv;
        }

        public Task OnExceptionAsync(ExceptionContext context)
        {
            //context.Exception 代表异常信息对象
            //context.ExceptionHandled = true;    //如果赋值为true 则其他ExceptionFilter不会执行
            //context.Result 的值会被输出给客户端
            string message = string.Empty;  
            if (hostEnv.IsDevelopment())
            {
                message = context.Exception.ToString(); 
            }
            else
            {
                message = "服务器发生未处理异常";
            }

            ObjectResult result = new ObjectResult(new { code = 500, message = message });
            result.StatusCode = 500;
            context.Result = result;
            context.ExceptionHandled = true;//执行到这,其他异常捕获就不会执行了
            return Task.CompletedTask;
        }
    }
}
using Microsoft.AspNetCore.Mvc.Filters;

namespace Part4_38
{
    public class LogExceptionFilter : IAsyncExceptionFilter
    {
        public Task OnExceptionAsync(ExceptionContext context)
        {
            return File.AppendAllTextAsync("f:/error.log", context.Exception.ToString());
        }
    }
}

然后在Program.cs中注入这两个异常捕获,要注意这个注入的顺序会影响执行顺序,先注入的会后执行:

builder.Services.Configure<MvcOptions>(options =>
{
    options.Filters.Add<MyExceptionFilter>();
    options.Filters.Add<LogExceptionFilter>();
});

Part4 – (38) ActionFilter Action筛选器

Action Filter

1、IAsyncActionFilter接口

2、多个Action Filter的链式执行。(一个ActionFilter中包含前代码和后代码,在执行方法的前后都可以执行一些逻辑)

.Net Core 教程 Part4 – (38)(39)(40)(41)过滤器 Filter

有两个ActionFilter 来进行编排,代码如下:

using Microsoft.AspNetCore.Mvc.Filters;

namespace Part4_38
{
    public class MyActionFilter1 : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
			//next 指向下一个筛选器 如果没有下一个筛选器 那么执行真正的Action方法
			Console.WriteLine("MyActionFilter 1:开始执行");
			ActionExecutedContext result = await next(); // next之前的是
			if (result.Exception != null)
			{
				Console.WriteLine("MyActionFilter 1:执行失败");
			}
			else
			{
				Console.WriteLine("MyActionFilter 1:执行成功");
			}		
		}
	}
}
using Microsoft.AspNetCore.Mvc.Filters;

namespace Part4_38
{
    public class MyActionFilter2 : IAsyncActionFilter
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
			     Console.WriteLine("MyActionFilter 2:开始执行");
			     ActionExecutedContext result = await next();
			     if (result.Exception != null)
			     {
				     Console.WriteLine("MyActionFilter 2:执行失败");
			     }
			     else
			     {
				     Console.WriteLine("MyActionFilter 2:执行成功");
			     }
		     }
    }
}
builder.Services.Configure<MvcOptions>(opt => { 
    opt.Filters.Add<MyActionFilter1>();
    opt.Filters.Add<MyActionFilter2>();
});

这样的话,就可以按照注入的顺序来执行:Action1前–> Action2前 –> Action2后 –> Action1后

注意:同步和异步的Action都可以被ActionFilter拦截。

.Net Core 教程 Part4 – (38)(39)(40)(41)过滤器 Filter

本文版权归个人技术分享站点所有,发布者:chaoqiang,转转请注明出处:http://www.zhengchaoqiang.com/1534.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-01-07 21:07
下一篇 2022-01-12 08:03

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

近期个人博客正在迁移中,原博客请移步此处,抱歉!