ASP.NET Core 常用拦截器、过滤器

2021年8月12日 2374点热度 0人点赞 0条评论
内容纲要

全局异常拦截器:

    /// <summary>
    /// Web 全局异常过滤器,处理 Web 中出现的、运行时未处理的异常
    /// </summary>
    public class WebGlobalExceptionFilter : IAsyncExceptionFilter
    {
        private readonly ILogger _logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loggerFactory"></param>
        public WebGlobalExceptionFilter(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<WebGlobalExceptionFilter>();
        }

        // json 序列化配置
        private static readonly JsonSerializerOptions JsonSetting = new JsonSerializerOptions()
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        };

        /// <summary>
        /// 异常处理
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task OnExceptionAsync(ExceptionContext context)
        {
            // 未经处理的异常
            if (!context.ExceptionHandled)
            {
                _logger.LogCritical(context.Exception, context.ActionDescriptor.DisplayName);
                var response = new ResponseJsonResultModel<object>()
                {
                    Code = (int)HttpStateCode.InternalServerError,
                    Msg = ResponseCode.SystemErrorValue,
                };

                context.Result = new ContentResult
                {
                    Content = JsonSerializer.Serialize(response, JsonSetting),
                    StatusCode = (int)HttpStateCode.InternalServerError,
                    ContentType = "application/json; charset=utf-8"
                };

                context.ExceptionHandled = true;
            }
            else
            {
                _logger.LogError(context.Exception, context.ActionDescriptor.DisplayName);
            }

            await Task.CompletedTask;
        }
    }

统一资源拦截器:


    /// <summary>
    /// 请求过滤验证,例如 400,405,415 等没带参数、metadate type 错误等
    /// </summary>
    public partial class ResourceFilter : IResourceFilter
    {
        private readonly ILogger _logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loggerFactory"></param>
        public ResourceFilter(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<WebGlobalExceptionFilter>();
        }

        /// <summary>
        /// 请求时
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
        }

        /// <summary>
        /// 请求后
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            // 验证通过
            if (context.ModelState.IsValid)
            {
                return;
            }

            int count = context.ModelState.Count;
            ValidationErrors[] errors = new ValidationErrors[count];
            int i = 0;
            foreach (var item in context.ModelState)
            {
                errors[i] = new ValidationErrors
                {
                    Member = item.Key,
                    Messages = item.Value.Errors?.Select(x => x.ErrorMessage).ToArray()
                };
                i++;
            }

            // 响应消息
            var result = new ResponseJsonResultModel<ValidationErrors[]>()
            {
                Code = (int)HttpStateCode.BadRequest,
                Msg = "请求格式不正确",
                Data = errors
            };

            _logger.LogDebug(System.Text.Json.JsonSerializer.Serialize(result));

            var objectResult = new BadRequestObjectResult(result);
            objectResult.StatusCode = (int)HttpStateCode.BadRequest;
            context.Result = objectResult;
        }
    }

统一模型验证器:

    /// <summary>
    /// 统一 Action 模型验证过滤器
    /// </summary>
    public class ActionInvalidModelFilter : IAsyncActionFilter
    {
        /// <summary>
        /// 拦截器
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            // 验证通过
            if (context.ModelState.IsValid)
            {
                await next();
                return;
            }

            int count = context.ModelState.Count;
            ValidationErrors[] errors = new ValidationErrors[count];
            int i = 0;
            foreach (var item in context.ModelState)
            {
                errors[i] = new ValidationErrors
                {
                    Member = item.Key,
                    Messages = item.Value.Errors?.Select(x => x.ErrorMessage).ToArray()
                };
                i++;
            }

            // 响应消息
            var result = new ResponseJsonResultModel<ValidationErrors[]>()
            {
                Code = (int)HttpStateCode.BadRequest,
                Msg = "请求参数不正确",
                Data = errors
            };

            var objectResult = new BadRequestObjectResult(result);
            objectResult.StatusCode = (int)HttpStateCode.BadRequest;
            context.Result = objectResult;
            await Task.CompletedTask;
        }
    }
```'

在进行依赖注入的时候,添加进去:
```csharp
            // 过滤器
            services.AddControllers(options =>
            {
                options.Filters.Add<WebGlobalExceptionFilter>();
                options.Filters.Add<ActionInvalidModelFilter>();
                options.Filters.Add<ResourceFilter>();
            })

痴者工良

高级程序员劝退师

文章评论