using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http; using Microsoft.Net.Http.Headers; using System.Net; using System.Text.Encodings.Web; using System.Text.Json; using System.Text.Unicode; using System; using System.Threading.Tasks; using Microsoft.IdentityModel.Logging; namespace Shentun.Peis { public class ErrorHandlerMiddleWare { //请求委托 private readonly RequestDelegate _next; // private readonly LogHelper _nlogger; public ErrorHandlerMiddleWare(RequestDelegate next //, LogHelper nlogger ) { this._next = next; // this._nlogger = nlogger; } public async Task Invoke(HttpContext context) { try { await this._next.Invoke(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private async Task HandleExceptionAsync(HttpContext context, Exception exception) { if (exception == null) return; await HandleErrorResultAsync(context, exception).ConfigureAwait(false); } private async Task HandleErrorResultAsync(HttpContext context, Exception exception) { //记录日志 // _nlogger.LogError(exception); //返回友好的提示 var response = context.Response; //清除原有HTTP上下文信息,为了明确指定程序出现异常,防止异常未被处理而后续当做正常操作执行 ClearHttpContext(context); //状态码 if (exception is UnauthorizedAccessException) response.StatusCode = (int)HttpStatusCode.Unauthorized; else if (exception is BadHttpRequestException) response.StatusCode = (int)HttpStatusCode.BadRequest; else if (response.StatusCode == 403 || response.StatusCode == 404) { } else response.StatusCode = (int)HttpStatusCode.InternalServerError; response.ContentType = context.Request.Headers["Accept"]; var result = new ApiResult { Code = 500, Message = exception.GetBaseException().Message }; if (response.ContentType.ToLower() != "application/x-www-form-urlencoded") { response.ContentType = "application/json"; } await response.WriteAsync(JsonSerializer.Serialize(result , new JsonSerializerOptions() { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase })).ConfigureAwait(false); } private static void ClearHttpContext(HttpContext context) { context.Response.Clear(); //因为可能创建了新的终结点,所以执行管道会有所调整,所以需要重新计算 context.SetEndpoint(endpoint: null); var routeValuesFeature = context.Features.Get(); routeValuesFeature?.RouteValues?.Clear(); } private static Task ClearCacheHeaders(object state) { //清除输出缓存相关 var headers = ((HttpResponse)state).Headers; headers[HeaderNames.CacheControl] = "no-cache"; headers[HeaderNames.Pragma] = "no-cache"; headers[HeaderNames.Expires] = "-1"; headers.Remove(HeaderNames.ETag); return Task.CompletedTask; } } }