DotNet Core 3.1 全局错误处理,未调用中间件

DotNetCore 3.1 global error handling, middle ware not getting called

我正在尝试在 .NetCore 3.1 webpai 中设置全局异常处理代码

我的目标是在应用程序退出之前使用 log4net 记录未处理的异常。

我尝试遵循几个教程,一个使用过滤器,几个使用中间件,当我完成并测试它时,当我因此抛出异常时,中间件永远不会被调用。

我已经有一个过滤器(它被注释掉以测试中间件以防它们交互)它确实有效,但不能使用 IOC 加载 ILogger 的实例

[HttpGet]
        [Route( "/ThrowException" )]
        public JqGridReturnCV ThrowException()
        {
            log.LogTrace( "AdStudentController::ThrowException() - in" );

            throw new Exception( "This is a test Exception" );

            log.LogTrace( "AdStudentController::ThrowException() - out" );
        }

这是我的中间件代码:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using log4net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using StudentPortal4Api.Dto;

namespace StudentPortal4Api.Utilities
{
    public class GlobalExceptionMiddleware
    {
        private readonly RequestDelegate next;
        public readonly  ILogger         log;

        public GlobalExceptionMiddleware( RequestDelegate _next, ILogger _log )
        {
            next = _next;
            log = _log;
        }

        public async Task Invoke( HttpContext context )
        {
            try
            {
                await next( context );
            }
            catch ( Exception ex )
            {
                var response = context.Response;
                response.ContentType = "application/json";

                switch ( ex )
                {
                    
                    default:
                        // unhandled error
                        log.Log( LogLevel.Error, " GlobalException:" + ex.ToString() ); 
                        break;
                }

                throw;
            }
        }
    }
    public class ErrorDetails
    {
        public int    StatusCode { get; set; }
        public string Message    { get; set; }
        public override string ToString()
        {
            return JsonConvert.SerializeObject( this );
        }
    }

    public static class ExceptionMiddlewareExtensions
    {
        public static void ConfigureExceptionHandler( this IApplicationBuilder app, ILogger logger )
        {
            app.UseExceptionHandler( appError =>
                                     {
                                         appError.Run( async context =>
                                                       {
                                                           context.Response.StatusCode  = (int) HttpStatusCode.InternalServerError;
                                                           context.Response.ContentType = "application/json";
                                                           var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
                                                           if ( contextFeature != null )
                                                           {
                                                               logger.LogError( $"Something went wrong: {contextFeature.Error}" );
                                                               await context.Response.WriteAsync( new ErrorDetails()
                                                                                                      {
                                                                                                          StatusCode = context.Response.StatusCode,
                                                                                                          Message    = "Internal Server Error."
                                                                                                      }.ToString() );
                                                           }
                                                       } );
                                     } );
        }
    }
}

这是我的配置方法,我怀疑我在注册它时做错了什么

            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure( IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, ILogger log )
            {
                //code removed for clarity
    
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
    
                //Code removed for clarity
    
                // global error handler
                app.UseMiddleware<GlobalExceptionMiddleware>();
                app.ConfigureExceptionHandler( log );
            }
        }
    }

有人看到我做错了什么了吗?

您有订单问题source

更改为:

 app.UseAuthorization();

 // global error handler
 app.UseMiddleware<GlobalExceptionMiddleware>(); //custom Middleware Must be before endpoints and after auth. 

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

您将不需要 app.UseExceptionHandler。