.net core различная обработка ошибок для контроллеров API и веб-страниц - PullRequest
1 голос
/ 11 июня 2019

Я пытаюсь настроить обработку исключений в новом проекте веб-приложения .net Core 2.2.

В настоящее время я пробовал два подхода:

  1. Использование встроенного ExceptionHandlers: app.UseExceptionHandler, app.UseStatusCodePages и т. Д. *
  2. Создал свое промежуточное программное обеспечение для обработки исключений, которые я добавил в конец этого вопроса.

Теперьглавная проблема заключается в том, что я могу использовать свое собственное промежуточное ПО, но (конечно) оно используется для всех запросов, а не только для вызовов API.

Чего я хотел бы добиться, так эторазделили логику исключений для веб-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; }
    }
}

1 Ответ

1 голос
/ 12 июня 2019

Вы не можете определить ошибку из исключения, я предлагаю вам попробовать сделать другой маршрут для MVC и веб-API. Для веб-API добавьте атрибут route с 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");
                });
            });
        });
...