什么是行为过滤器
用于在控制器方法的执行前后或异常发生时执行额外的逻辑处理。它提供了一种能力,允许开发人员通过在控制器上应用过滤器来拦截请求并对其进行修改或处理。
特点
-
可以统一处理某一请求或响应的逻辑,如验证输入、日志记录、异常处理等。
-
可以对匹配某些条件的请求或响应进行过滤,过滤器可以根据需要选择是否继续执行、修改请求或响应等。
-
可以实现全局过滤器,这些过滤器会对整个应用程序中的请求和响应进行处理。
-
可以实现局部过滤器,这些过滤器仅作用于某个特定的控制器或方法,适用于需要特定响应的场景下。
四种类型
-
Authorization Filters:用于控制访问授权的过滤器,可以决定请求是否被授权访问某一个特定的操作。
-
Action Filters:用于在执行控制器方法之前或之后进行某些额外的操作,如记录日志、请求或响应的修改等。
-
Result Filters:在执行结果前或后进行操作,如修改响应、缓存结果、记录日志等。
-
Exception Filters:用于处理请求过程中发生的未处理异常,如记录错误、返回友好信息等。
统一处理应用程序中的请求和响应,并通过配置过滤器链灵活地进行请求的处理和过滤。
异常过滤器
用于在发生未处理异常时执行额外的逻辑处理。可以在发生异常时捕获并对其进行处理,以便记录错误、返回自定义错误页面或友好的错误信息等。
try
{
// 可能会抛出异常的代码
}
catch (Exception ex) when (ex is MyCustomException || ex.Message.Contains("特定条件"))
{
// 异常过滤器,只处理满足条件的异常
// 执行对异常的处理逻辑
}
特点
-
精确筛选异常:根据特定条件筛选和处理异常。通过使用when子句,可以根据异常类型、属性、消息内容等进行条件判断,只处理满足条件的异常。这种精确的筛选功能可以使异常处理更加准确和可控,减少误处理或无关异常被捕获的情况。
-
增强代码可读性:异常过滤器可以在catch块中指定清晰的条件表达式,使代码更加可读和易于理解。直观地了解哪些异常会被捕获和处理,以及异常被处理的具体逻辑。
-
分离异常处理逻辑:使用异常过滤器可以将异常处理逻辑与一般的catch块分离开来。通过将异常过滤器放在单独的catch块中,可以专门处理特定条件的异常,从而提高代码的可维护性和可扩展性。
-
灵活性和扩展性:允许自定义条件来选择需要处理的异常,从而提供了更大的灵活性和扩展性。根据具体需求,根据异常类型、属性或其他自定义条件来设计过滤器,以便根据不同的情况执行相应的异常处理逻辑。
-
减少代码重复:异常过滤器可以在多个catch块之间共享并复用。如果不使用异常过滤器,可能需要编写多个catch块来处理不同类型或条件的异常,导致代码重复。而使用异常过滤器,可以将这些共享的筛选条件代码放在一个catch块中,减少了代码冗余和维护成本。
缺点
1.嵌套过深:当嵌套多个异常过滤器时,可能会导致异常过滤器嵌套过深,使代码难以阅读和管理。
2.代码层次较深:异常过滤器具有特定的代码层次结构,必须放置在特定的程序块中(如catch块),这可能会使代码的层次结构更加复杂。
3.可能会造成性能开销:使用异常过滤器可能会造成一定的性能开销,因为每次捕获异常时,运行时都需要检查是否匹配异常过滤器。
使用
定义参数 ,来获取状态
/// <summary>
/// 过滤器参数
/// </summary>
public class ResulrWapper
{
public int code { get; set; }
public string message { get; set; }
public object data { get; set; }
}
其次写一个类,进行继承行为和异常过滤器的类
/// <summary>
/// 行为过滤器和全局异常过滤器
/// </summary>
public class ResultWrapperFilter : IActionFilter, IExceptionFilter
{
/// <summary>
/// 在Action方法调用后,result方法调用前执行,使用场景:异常处理。
/// </summary>
/// <param name="context"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnActionExecuted(ActionExecutedContext context)
{
//使用了两个 if 语句来检查 context.Result 的类型,并分别处理 ObjectResult 和 JsonResult。
//ObjectResult :通用的结果对象,可以将任何类型的对象作为响应返回,还可以设置状态码、响应头、其它属性
//JsonResult 是 ObjectResult 的一个具体实现,专门用于返回 JSON 格式的响应。
if (context.Result is ObjectResult obj)
{
context.Result = new ObjectResult(new ResulrWapper
{
code = 200,
data = obj.Value
});
}
if (context.Result is JsonResult json)
{
context.Result = new ObjectResult(new ResulrWapper
{
code = 200,
data = json.Value
});
}
}
/// <summary>
/// 在Action方法调用前使用,使用场景:如何验证登录等
/// </summary>
/// <param name="context"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnActionExecuting(ActionExecutingContext context)
{
}
/// <summary>
/// 负责针对捕捉到异常的数据触发的函数。(全局异常)
/// </summary>
/// <param name="context"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnException(ExceptionContext context)
{
context.Result = new ObjectResult(new ResulrWapper
{
code = 500,
message = context.Exception.Message,
});
context.ExceptionHandled = true;
}
}
写完之后切记一定要去注册,否则使用无效
builder.Services.AddControllers(m =>
{
m.Filters.Add<ResultWrapperFilter>();
});