.Net Core3.0 WebApi 十二:自定义全局消息返回过滤中间件

.Net Core3.0 WebApi 目录

.Net Core MVC理解新管道处理模型、中间件

应用场景

有的时候,接口请求会返回一些系统的状态码,如404,401,403等,我们会希望自定义这些返回消息,这个时候我们可以自定义一个中间件来在消息返回之前处理消息。

定义中间件

Models项目新建Errors文件夹,新建ErrorModel,定义错误消息返回格式。

namespace WebApi.Core.Models.Errors
{
    /// <summary>
    /// 错误实体
    /// </summary>
    public class ErrorModel
    {
        /// <summary>
        /// 状态码
        /// </summary>
        public int code { get; set; } = 500;

        /// <summary>
        /// 错误信息
        /// </summary>
        public string msg { get; set; }

        /// <summary>
        /// 错误详情
        /// </summary>
        public string detail { get; set; }

        /// <summary>
        /// 时间戳
        /// </summary>
        public string timestamp { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
    }
}

Infrastructure的JsonHelper类里面新加一个方法

namespace WebApi.Core.Infrastructure.Helpers
{
    public class JsonHelper
    {
        /// <summary>
        /// 转Json回HttpResponseMessage
        /// </summary>
        /// <param name="code"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static string ToJson(object result)
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(result);
        }
    }
}

项目新建Middleware文件夹,新建CustomExceptionMiddleware.cs

namespace WebApi.Core.Api.Middleware
{
    public class CustomExceptionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILoggerHelper _logger;
        public CustomExceptionMiddleware(RequestDelegate next, ILoggerHelper logger)
        {
            _next = next;
            _logger = logger;
        }
        public async Task Invoke(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message, ex); // 日志记录
                await HandleExceptionAsync(httpContext, ex.Message);
            }
            finally
            {
                var statusCode = httpContext.Response.StatusCode;
                var msg = "";
                switch (statusCode)
                {
                    case 401:
                        msg = "未授权";
                        break;
                    case 403:
                        msg = "拒绝访问";
                        break;
                    case 404:
                        msg = "未找到服务";
                        break;
                    case 405:
                        msg = "405 Method Not Allowed";
                        break;
                    case 502:
                        msg = "请求错误";
                        break;
                }
                if (!string.IsNullOrWhiteSpace(msg))
                {
                    await HandleExceptionAsync(httpContext, msg);
                }
            }
        }
        ///
        private async Task HandleExceptionAsync(HttpContext httpContext, string msg)
        {
            ErrorModel error = new ErrorModel
            {
                code = httpContext.Response.StatusCode,
                msg = msg
            };
            var result = JsonHelper.ToJson(error);
            httpContext.Response.ContentType = "application/json;charset=utf-8";
            await httpContext.Response.WriteAsync(result).ConfigureAwait(false);
        }
    }

    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class CustomExceptionMiddlewareExtensions
    {
        public static IApplicationBuilder UseCustomExceptionMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<CustomExceptionMiddleware>();
        }
    }
}

使用中间件

startup.cs的Configure方法注册中间件

app.UseCustomExceptionMiddleware();

运行项目,访问一个需要认证的接口,可以看到消息已经是我们自定义的格式了。

 

posted @ 2020-10-15 00:29  冰乐  阅读(1154)  评论(0编辑  收藏  举报