首页 > 解决方案 > .net 核心对 API 和网页控制器的不同错误处理

问题描述

我正在尝试在新的 .net Core 2.2 Web 应用程序项目中设置异常处理。

目前我尝试了两种方法 - 成为

  1. 使用内置的 ExceptionHandlers: app.UseExceptionHandler, app.UseStatusCodePages, 等等...
  2. 创建了我自己的中间件来处理我添加到这个问题底部的异常。

现在,主要问题是我可以使用我自己的自定义中间件,但是(当然)这用于所有请求,而不仅仅是 API 调用。

我想要实现的是将 Web API 和网页的异常逻辑分开,这样我就可以使用我的自定义中间件和 API 的返回格式,app.UseDeveloperExceptionPage()例如用于网页。

异常中间件供参考:

public static class ExceptionMiddleware
{
    public static void ConfigureExceptionHandler(this IApplicationBuilder app, ILoggerFactory loggerFactory,
        bool includeStackTrace = false)
    {
        app.UseExceptionHandler(builder =>
            builder.Run(async context =>
            {
                var logger = loggerFactory.CreateLogger(nameof(ExceptionMiddleware));

                // Set the response status code
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
                context.Response.ContentType = "application/json";

                var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
                if (contextFeature != null)
                {
                    // Get the current exception
                    var currentException = contextFeature.Error;
                    logger.LogError(currentException, $"Something went wrong: {currentException}");

                    ErrorDetails errorDetails;

                    if (includeStackTrace)
                        errorDetails = new ExtendedErrorDetails
                        {
                            StatusCode = (HttpStatusCode) context.Response.StatusCode,
                            Message = currentException.Message,
                            StackTrace = currentException.StackTrace
                        };
                    else
                        errorDetails = new ErrorDetails
                        {
                            StatusCode = (HttpStatusCode) context.Response.StatusCode,
                            Message = "Internal Server Error."
                        };

                    // Write the response
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(errorDetails));
                }
            }));
    }

    private class ErrorDetails
    {
        public HttpStatusCode StatusCode { [UsedImplicitly] get; set; }

        public string Message { [UsedImplicitly] get; set; }
    }

    private class ExtendedErrorDetails : ErrorDetails
    {
        public string StackTrace { [UsedImplicitly] get; set; }
    }
}

标签: c#asp.net-coreasp.net-core-mvcasp.net-core-webapi

解决方案


您无法从异常中识别错误,我建议您尝试为 mvc 和 web api 制定不同的路线。对于 web api,添加属性路由api,然后检查中间件或异常处理程序中的请求路径,如

    app.UseExceptionHandler(builder =>
    {
            builder.Run(async context =>
            {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;                   
                    var error = context.Features.Get<IExceptionHandlerFeature>() as ExceptionHandlerFeature;
                    var requestPath = error.Path;                    
            });
    });

更新:

        app.UseDeveloperExceptionPage();

        app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), subApp =>
        {
            subApp.UseExceptionHandler(builder =>
            {
                builder.Run(async context =>
                {
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    await context.Response.WriteAsync("Error");
                });
            });
        });

推荐阅读