You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.6 KiB

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<IRouteValuesFeature>();
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;
}
}
}