Files
StopShopping/StopShopping.Api/Middlewares/GlobalExceptionHandlerMiddleware.cs
2026-03-30 11:07:30 +08:00

107 lines
3.8 KiB
C#

using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
using StopShopping.Services.Models.Resp;
namespace StopShopping.Api.Middlewares;
public class GlobalExceptionHandlerMiddleware
{
public GlobalExceptionHandlerMiddleware(RequestDelegate requestDelegate,
ILogger<GlobalExceptionHandlerMiddleware> logger,
IProblemDetailsService problemDetailsService)
{
_next = requestDelegate;
_logger = logger;
_problemDetailsService = problemDetailsService;
}
private readonly RequestDelegate _next;
private readonly ILogger<GlobalExceptionHandlerMiddleware> _logger;
private readonly IProblemDetailsService _problemDetailsService;
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext);
httpContext.Response.OnStarting(async () =>
{
var antiforgeryFeature = httpContext.Features.Get<IAntiforgeryValidationFeature>();
if (null != antiforgeryFeature && !antiforgeryFeature.IsValid)
{
var problemDetails = new ProblemDetails
{
Detail = antiforgeryFeature.Error?.Message,
Instance = httpContext.Request.Path,
Status = StatusCodes.Status400BadRequest,
Title = "CSRF 错误",
};
problemDetails.AddErrorCode(ProblemDetailsCodes.CsrfValidationFailed);
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
httpContext.Response.ContentType = "application/problem+json";
await _problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = httpContext,
ProblemDetails = problemDetails
});
}
await Task.CompletedTask;
});
}
catch (BadHttpRequestException ex)
{
_logger.LogError(ex, "参数错误");
var problemDetails = new ProblemDetails
{
Detail = ex.Message,
Instance = httpContext.Request.Path,
Status = StatusCodes.Status400BadRequest,
Title = "参数错误",
};
problemDetails.AddErrorCode(ProblemDetailsCodes.BadParameters);
httpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
httpContext.Response.ContentType = "application/problem+json";
await _problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = httpContext,
ProblemDetails = problemDetails
});
}
catch (ServiceException ex)//业务层抛出提示
{
await httpContext.Response.WriteAsJsonAsync(ApiResponse.Failed(ex.Message));
}
catch (Exception ex)
{
_logger.LogCritical(ex, "意外的异常");
var problemDetails = new ProblemDetails
{
Detail = ex.Message,
Instance = httpContext.Request.Path,
Status = StatusCodes.Status500InternalServerError,
Title = "服务器错误",
};
problemDetails.AddErrorCode(ProblemDetailsCodes.ServerError);
httpContext.Response.StatusCode = StatusCodes.Status500InternalServerError;
httpContext.Response.ContentType = "application/problem+json";
await _problemDetailsService.WriteAsync(new ProblemDetailsContext
{
HttpContext = httpContext,
ProblemDetails = problemDetails,
});
}
}
}