C# Webapi Filter 过滤器 - 生命周期钩子函数 - Exception Filter 基础

发布时间 2023-10-28 12:08:29作者: 流浪のwolf

什么是Filter ?

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

2. ASP.NET Core 中的Filter五种类型,Authorization ,filter ,resource filter ,action filter ,exception fitler ,result filter ;

3. 所有的筛选器都有异步和同步两种版本 ;eg:IActionFilter,IAsyncActionFilter ;

 

Action filte讲解:

比如在controller 方法中出现未处理异常 ;文件 

("f:/1.txt");  不存在 ;
using Microsoft.AspNetCore.Mvc;

namespace Filter.Controllers
{
    [ApiController]
    [Route("ap/[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        [HttpGet(Name = "GetWeatherForecast")]
        public string Test1()
        {
            // 文件并不存在会抛出错误
            string s = System.IO.File.ReadAllText("f:/1.txt");  // 读取文件
            return s;
        }

    };
}

 对于这种处理可以使用 action filter 劫持并对其做出相应的处理 ;开发环境和生产环境 ;

开发环境要抛出详细的信息,方便我们调试,但是在生产环境,我们只需要抛出 500 服务器出现位置错误即可 ;

 

1. 注册Filter 

    // 注册过滤器
            builder.Services.Configure<MvcOptions>(opt =>
            {
                opt.Filters.Add<MyExceptionFilter>();
            });

2. 具体服务

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

namespace Filter
{
    public class MyExceptionFilter : IAsyncExceptionFilter
    {
        public readonly IWebHostEnvironment hostEnv;

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

        /// 处理异常
        public Task OnExceptionAsync(ExceptionContext context)
        {
            // context.Exception 代表异常信息对象
            // context.ExceptionHandled 赋值为 true ,下面所有的 filter 就不会在执行 ;
            // context.result 会被输出给客户端
            string msg;
            if (hostEnv.IsDevelopment())
            {
                // 开发环境
                msg = context.Exception.ToString();
            }
            else
            {
                // 生产环境
                msg = "服务器发生未处理异常";
            }
            ObjectResult objResult = new ObjectResult(new { code = 500, message = msg });
            context.Result = objResult;
            context.ExceptionHandled = true;
            return Task.CompletedTask;
        }
    }
}