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 logger, IProblemDetailsService problemDetailsService) { _next = requestDelegate; _logger = logger; _problemDetailsService = problemDetailsService; } private readonly RequestDelegate _next; private readonly ILogger _logger; private readonly IProblemDetailsService _problemDetailsService; public async Task InvokeAsync(HttpContext httpContext) { try { await _next(httpContext); httpContext.Response.OnStarting(async () => { var antiforgeryFeature = httpContext.Features.Get(); 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, }); } } }