using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Text.Json; using System.Threading.Tasks; using VOL.Core.Const; using VOL.Core.Enums; using VOL.Core.Extensions; using VOL.Core.Services; namespace VOL.Core.Middleware { public class ExceptionHandlerMiddleWare { private readonly RequestDelegate next; public ExceptionHandlerMiddleWare(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context) { try { (context.RequestServices.GetService(typeof(ActionObserver)) as ActionObserver).RequestDate = DateTime.Now; await next(context); int statusCode = context.Response.StatusCode; if (StatusCodeMessagesHelper.ContainKey(statusCode) && statusCode >= StatusCodes.Status400BadRequest) { string msg = StatusCodeMessagesHelper.GetValue(statusCode); await WirteAsync(context, msg); } } catch (Exception exception) { // (context.RequestServices.GetService(typeof(ActionObserver)) as ActionObserver).IsWrite = false; string message = exception.Message + exception.InnerException ?.InnerException ?.Message + exception.InnerException + exception.StackTrace; await WirteAsync(context, message); } } private static async Task WirteAsync(HttpContext context, string message) { if (context.Response.HasStarted) return; int originalStatusCode = context.Response.StatusCode != StatusCodes.Status200OK ? context.Response.StatusCode : StatusCodes.Status500InternalServerError; // 如果状态码是200,则假设500内部服务器错误 context.Response.StatusCode = StatusCodes.Status200OK; context.Response.ContentType = ApplicationContentType.JSON; var stream = context.Response.Body; string json = new Utilities.WebResponseContent { Message = "Web服务器服务器内部状态未知异常", Status = false, Code = originalStatusCode, Data = message }.Serialize(); var request = HttpRequestResponseFormat.FormatRequest(context.Request).Result; VOL.Core.Services.Logger.Error(LoggerType.Exception, request, json); await JsonSerializer.SerializeAsync(stream, json, new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase } ); } } public class StatusCodeMessagesHelper { private static readonly Dictionary StatusCodeMessages = new() { { StatusCodes.Status100Continue, "继续" }, { StatusCodes.Status101SwitchingProtocols, "切换协议" }, { StatusCodes.Status200OK, "请求成功" }, { StatusCodes.Status201Created, "已创建" }, { StatusCodes.Status202Accepted, "已接受" }, { StatusCodes.Status203NonAuthoritative, "非权威信息" }, { StatusCodes.Status204NoContent, "无内容" }, { StatusCodes.Status205ResetContent, "重置内容" }, { StatusCodes.Status206PartialContent, "部分内容" }, { StatusCodes.Status300MultipleChoices, "多种选择" }, { StatusCodes.Status301MovedPermanently, "永久移动" }, { StatusCodes.Status302Found, "找到" }, { StatusCodes.Status303SeeOther, "参见其他" }, { StatusCodes.Status304NotModified, "未修改" }, { StatusCodes.Status305UseProxy, "使用代理" }, { StatusCodes.Status307TemporaryRedirect, "临时重定向" }, { StatusCodes.Status400BadRequest, "错误请求" }, { StatusCodes.Status401Unauthorized, "未授权" }, { StatusCodes.Status402PaymentRequired, "需要付款" }, { StatusCodes.Status403Forbidden, "禁止" }, { StatusCodes.Status404NotFound, "未找到" }, { StatusCodes.Status405MethodNotAllowed, "方法不允许" }, { StatusCodes.Status406NotAcceptable, "不可接受" }, { StatusCodes.Status407ProxyAuthenticationRequired, "需要代理身份验证" }, { StatusCodes.Status408RequestTimeout, "请求超时" }, { StatusCodes.Status409Conflict, "冲突" }, { StatusCodes.Status410Gone, "已消失" }, { StatusCodes.Status411LengthRequired, "需要长度" }, { StatusCodes.Status412PreconditionFailed, "前提条件失败" }, { StatusCodes.Status413RequestEntityTooLarge, "请求实体太大" }, { StatusCodes.Status414RequestUriTooLong, "请求URI太长" }, { StatusCodes.Status415UnsupportedMediaType, "不支持的媒体类型" }, { StatusCodes.Status416RequestedRangeNotSatisfiable, "请求范围不满足" }, { StatusCodes.Status417ExpectationFailed, "期望失败" }, { StatusCodes.Status500InternalServerError, "内部服务器错误" }, { StatusCodes.Status501NotImplemented, "未实现" }, { StatusCodes.Status502BadGateway, "错误网关" }, { StatusCodes.Status503ServiceUnavailable, "服务不可用" }, { StatusCodes.Status504GatewayTimeout, "网关超时" }, }; public static bool ContainKey(int code) { return StatusCodeMessages.ContainsKey(code); } public static string GetValue(int code) { return StatusCodeMessages.GetValue(code); } } }