【问题标题】:Global Exception Handling using Middleware not working in ASP.Net Core app使用中间件的全局异常处理在 ASP.Net Core 应用程序中不起作用
【发布时间】: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 中不起作用以及如何使它起作用。无论如何,谢谢你为我腾出一些时间。

标签: c# asp.net-core exception asp.net-web-api asp.net-core-middleware


【解决方案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,
});

【讨论】:

  • 我也试过了。它似乎仍然不起作用。
猜你喜欢
  • 2018-09-11
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 2021-10-14
  • 2019-07-26
  • 1970-01-01
相关资源
最近更新 更多