使用中间件的全局异常处理在 ASP.Net Core 应用程序中不起作用
Posted
技术标签:
【中文标题】使用中间件的全局异常处理在 ASP.Net Core 应用程序中不起作用【英文标题】:Global Exception Handling using Middleware not working in ASP.Net Core app 【发布时间】:2021-12-26 14:56:54 【问题描述】:我一直在尝试在我的 ASP.Net Core Web API 中设置使用自定义中间件的全局异常处理。我需要使用 Serilog 将它们记录到日志文件中。我尝试了很多,但我无法让它工作。希望这里的朋友能帮帮我。
我的自定义中间件:
public class ExceptionHandlingMiddleware
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionHandlingMiddleware> logger;
public ExceptionHandlingMiddleware()
public ExceptionHandlingMiddleware(
RequestDelegate next,
ILogger<ExceptionHandlingMiddleware> logger)
_next = next ?? throw new ArgumentNullException(nameof(next));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
public async Task InvokeAsync(HttpContext context)
if (context is null)
throw new ArgumentNullException(nameof(context));
try
await _next.Invoke(context);
catch (Exception ex)
await HandleExceptionAsync(context, ex);
private async Task HandleExceptionAsync(
HttpContext context,
Exception exception)
try
int statusCode = 0;
if (context is null)
throw new ArgumentNullException(nameof(context));
if (exception is null)
throw new ArgumentNullException(nameof(exception));
this.logger.LogError(exception.ToString());
CustomApiResponse<CustomApiErrorResponse> errorResponse = null;
if (exception is MyException myExceptionInfo)
statusCode = myExceptionInfo.StatusCode == default ? (int)HttpStatusCode.InternalServerError : myExceptionInfo.StatusCode;
errorResponse = new CustomApiResponse<CustomApiErrorResponse>()
StatusCode = statusCode,
TraceId = context.TraceIdentifier,
Response = new CustomApiErrorResponse()
Message = myExceptionInfo.ErrorMessage,
StackTrace = myExceptionInfo.StackTrace
;
else
statusCode = (int)HttpStatusCode.InternalServerError;
const string message = "Unexpected error";
errorResponse = new CustomApiResponse<CustomApiErrorResponse>()
StatusCode = (int)HttpStatusCode.InternalServerError,
Response = new CustomApiErrorResponse()
Message = message,
,
TraceId = context.TraceIdentifier
;
var responseContent = JsonConvert.SerializeObject(errorResponse);
context.Response.ContentType = "application/json";
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseContent);
catch (Exception ex)
this.logger.LogError(ex.ToString());
throw;
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
//app.UseExceptionHandlerMiddleware();
app.UseExceptionHandler(new ExceptionHandlerOptions
ExceptionHandler = new ExceptionHandlingMiddleware().InvokeAsync,
);
//app.UseExceptionHandler(options =>
//
// options.Run(async context =>
//
// // Exception Handling Code
// );
//
我哪里错了?我还需要做什么才能让它工作吗?异常会从代码中抛出,但不会被中间件捕获。请朋友们帮帮我。
更新
我使用的是 GraphQL 而不是 REST。所以我的应用程序中没有控制器。这是造成这个问题的原因吗?
【问题讨论】:
嗨@Arjun D Nair,I'm using GraphQL instead of REST. So there are no controllers in my app. Is that a reason for this issue?
我想是的。我在 api 控制器中测试。效果很好。
嗨@Rena,感谢您的支持。我也提到了我使用 REST 完成的几个旧项目。在那些项目中它工作得很好,但在这个项目中却不行。
嗨@Rena,似乎使用 GraphQL 是个问题。我也使用 REST API 示例项目对其进行了测试,并且运行良好。现在我需要弄清楚为什么它在 GraphQL 中不起作用以及如何使它起作用。无论如何,谢谢你为我腾出一些时间。
【参考方案1】:
确保您的ExceptionHandlingMiddleware.cs
位于Middleware
文件夹中。
并在您的配置方法中使用以下内容:-
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseMiddleware<ExceptionHandlingMiddleware>();
...
它将解决您的问题。如果仍然无法解决,请告诉我。
【讨论】:
嗨,Pritom,我按照你说的试过了。我的中间件位于我的解决方案中的一个类库项目中。我将其移至 Startup.cs 文件所在的主 API 项目,并将文件夹重命名为 Middleware 并更改了命名空间。它似乎仍然不起作用。 @ArjunDNair 能给我看看你的项目文件夹目录图片吗? 对不起,这是一个受版权保护的项目。 @ArjunDNair 我实际上只是想查看您的启动文件、中间件文件夹及其异常类位置。 我猜是位置问题。我想确认一下。如果不是位置问题,我会更新你的异常处理类代码。【参考方案2】:尝试像这样改变你的创业公司:
app.UseMiddleware<ExceptionHandlingMiddleware>();
而不是
app.UseExceptionHandler(new ExceptionHandlerOptions
ExceptionHandler = new ExceptionHandlingMiddleware().InvokeAsync,
);
【讨论】:
我也试过了。它似乎仍然不起作用。以上是关于使用中间件的全局异常处理在 ASP.Net Core 应用程序中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用 NLog 在 ASP.NET Web API 2.1 中进行全局异常处理?
ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常