Как в действии обработки ошибок определить, должен ли я возвращать веб-представление или ответ API

В проекте Asp.net Core у меня есть контроллеры как веб-интерфейса, так и веб-API. Я подписался на https://www.devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api и включен в startup.cs:

app.UseStatusCodePagesWithReExecute("/Error/error/{0}");
app.UseExceptionHandler("/Error/error/500");

И добавлено действие по обработке ошибок в ErrorController:

[Route("error/{code}")]
public IActionResult Error(int code)
{
    return new ObjectResult(new ApiResponse(code));
}

Это хорошо для веб-API, но не для веб-страниц. Для api мы хотим вернуть настраиваемый объект (сериализованный как JSON), но для пользовательского интерфейса мы хотим вернуть настраиваемое представление. Я хочу написать что-то вроде

public IActionResult Error(int code)
{
     if(CalledFromApiClient())
     {
           return new ObjectResult(new ApiResponse(code));
     }
     else
        return View(“Error”);
}

Вопрос в том, как реализовать CalledFromApiClient?

Я думаю сохранить все контроллеры api в подпапке / пространстве имен api и использовать стек вызовов, чтобы найти, было ли исключение, выброшенное из контроллера api, или нет. Должно сработать, но выглядит неважно.

Есть способ лучше?

            


person Michael Freidgeim    schedule 24.11.2017    source источник
comment
Отметьте заголовок Accept (согласование содержимого). Если запрос запрашивает JSON, дайте ему JSON. Если он запрашивает HTML, верните это   -  person Nkosi    schedule 25.11.2017


Ответы (1)


Наконец-то я нашел ответ в блоге того же автора https://www.devtrends.co.uk/blog/conditional-middleware-based-on-request-in-asp.net-core

Типичным примером этого требования является проект с действиями как MVC, так и API, в котором вы хотите, чтобы обработка ошибок была различной для каждого из них.

Мы предполагаем, что URL-адреса следуют соглашению о том, что действия контроллера api начинаются с сегмента "api".

// returns Api error response
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    appBuilder.UseStatusCodePagesWithReExecute("/apierror/{0}");
appBuilder.UseExceptionHandler("/apierror/500");
});
// returns MVC error page
app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
    appBuilder.UseStatusCodePagesWithReExecute("/error/{0}");
appBuilder.UseExceptionHandler("/error/500");
});
person Michael Freidgeim    schedule 29.12.2017