Asp.Netcore使用Filter来实现接口的全局异常拦截,以及前置拦截和后置拦截

原文链接:https://blog.csdn.net/qq_38762313/article/details/85234594

 

全局异常拦截器:
       解决写每个接口都需要去做容错而添加try{}catch{},有了该异常拦截器后,所有接口都不需要去添加异常处理。

实现方式:

       第一步:新建一个类继承 IExceptionFilter,添加 using Microsoft.AspNetCore.Mvc.Filters;该类的名称命名要求是:后缀必须ExceptionFilter,例如:GlobalExceptionFilter。该类必须实现OnException 这个方法。这个方法是当异常发生时会进入。 例如下面的例子:

public class ExceptionFilter : IExceptionFilter
    { 

        /// <summary>
        /// 发生异常时进入
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            if (context.ExceptionHandled == false)
            {
                context.Result = new ContentResult
                {
                    Content = context.Exception.Message,//这里是把异常抛出。也可以不抛出。
                    StatusCode = StatusCodes.Status200OK,
                    ContentType = "text/html;charset=utf-8"
                };
            }
            context.ExceptionHandled = true;
          }

        /// <summary>
        /// 异步发生异常时进入
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task OnExceptionAsync(ExceptionContext context)
        {
            OnException(context);
            return Task.CompletedTask;
        }

       }
 第二步:修改Stup.cs文件如下即完成。

                  .AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1) 把这段代码修改为:

.AddMvc(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
 

前置和后置拦截器:
       解决接口入参数的合法性验证问题,以及对参数等前期的信息处理等。例如:访问的合法性等。

实现方式:

       第一步:异常拦截器很相似,新建一个类继承 IActionFilter,添加 using Microsoft.AspNetCore.Mvc.Filters;该类的名称命名要求是:后缀必须ActionFilter,例如:GlobalActionFilter。该类必须实现OnActionExecuted和OnActionExecuting这两个方法。这个方法是当异常发生时会进入。 例如下面的例子:

public class GlobalActionFilter : IActionFilter
{
/// <summary>
/// Action 执行后拦截
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{

}

/// <summary>
/// Action 执行前拦截[模型验证应该在此处先处理]
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
context.HttpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";//解决拦截器添加后跨域不生效的问题
if (!context.ModelState.IsValid)//验证参数的合法性问题。返回错误信息
{
///模型有效性验证失败处理逻辑...比如将提示信息返回
StringBuilder stringBuilder = new StringBuilder();
///模型有效性验证失败处理逻辑.....
///如返回错误信息,这里可自动包装
foreach (var item in context.ModelState.Values)
{
foreach (var error in item.Errors)
{
stringBuilder.Append($"{ error.ErrorMessage}|");
}
}

context.Result = new ContentResult
{
Content = stringBuilder.ToString(),
StatusCode = StatusCodes.Status200OK,
ContentType = "text/html;charset=utf-8"
};
}

}
}
第二步:修改Stup.cs文件如下即完成。

                  .AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1) 把这段代码修改为:

.AddMvc(options =>
{
options.Filters.Add<GlobalActionFilter>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
模型和参数验证的使用方式[配合前置拦截器,开发人员可以不用操心验证和返回错误信息]:

在参数前面添加特性,常用的三个特性如下

接收Query的写法

[HttpGet("test")]
public object test([FromQuery] [Required(ErrorMessage = "名称不能为空")][MaxLength(5,ErrorMessage = "名称长度不能大于5")][MinLength(3,ErrorMessage = "名称最小长度为3")] string name)
{

}
一个参数可以同时写多个特性进行验证。

接收Body的写法

该特性验证要在实体类上写,接参时用实体类去接,这样验证通用起到效果。

例如:

       

[HttpPost("test")]
public object test([FromBody] Users user)
{

}

public class Users
{
[Required(ErrorMessage = "名称不能为空")]
public string Name{get;set;};

public int Age{get;set;};
}

相关文章