ASP.Net Core 2 错误处理:如何在 Http 响应中返回格式化的异常详细信息



我正在寻找一种方法来返回调用我的 Web API 方法时发生的任何异常的详细信息。

默认情况下,在生产环境中,错误 500"内部服务器错误"是 API 返回的唯一信息。

它是一个私有 API,不会在互联网上发布,调用方应用程序需要获取并存储所有详细信息,以防异常。

异常详细信息可以是 HttpResponse 内容中格式化的 JSON,允许调用方读取 Message 属性和异常的 StackTraceString 属性(没有像 UseDeveloperExceptionPage 配置这样的 HTTP 页面(。

目前,默认的启动配置方法是:

public class Startup
{   
    [...]
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
    {
        loggerFactory.AddNLog();
        env.ConfigureNLog(Path.Combine(AppContext.BaseDirectory, "nlog.config"));
        if ( env.IsDevelopment() )
            app.UseDeveloperExceptionPage();
        else
            app.UseStatusCodePages();
        app.UseMvc();
    }
}

你可以编写一个自定义中间件,它拦截所有异常并将它们返回给调用方:

public class ExceptionHandler
{
    private readonly RequestDelegate _next;
    public ExceptionHandler(RequestDelegate next)
    {
        _next = next;
    }
    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next.Invoke(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    private async Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        var response = context.Response;
        response.ContentType = "application/json";
        response.StatusCode = (int)HttpStatusCode.InternalServerError;
        await response.WriteAsync(JsonConvert.SerializeObject(new
        {
            // customize as you need
            error = new
            {
                message = exception.Message,
                exception = exception.GetType().Name
            }
        }));
    }
}

并在启动配置方法中注册它:

if (env.IsDevelopment())
    app.UseDeveloperExceptionPage();
else
   app.UseMiddleware<ExceptionHandler>();

除了中间件,您可以创建 ActionFilterAttribute 并更改 IActionResult

下面是一个简单的示例属性,对于所有未处理的异常,使用异常方法返回 400 个错误请求。

public class MyUnhandledExceptionFilter : ActionFilterAttribute, IExceptionFilter
{        
    public void OnException(ExceptionContext context)
    {           
        context.Result = new BadRequestObjectResult(context.Exception.Message);
    }
}

然后,在启动的配置服务方法中注册它,如下所示

services.AddMvc(options =>
        {
            options.Filters.Add(typeof(MyUnhandledExceptionFilter));
        })

这仅捕获到达 MVC 的异常,在大多数情况下,这是您需要的

记得在UseMvc(或.Net Core 3中的UseRouting (之前添加它,因为顺序很重要!!!!

        app.UseRouting ();
        app.UseMiddleware (typeof (ErrorHandlingMiddleware));

最新更新