использование UseExceptionHandler () с обработкой API и обработкой 404 в ASP. NET Core 2 - PullRequest
0 голосов
/ 10 июля 2020

У меня следующая ситуация:

  • ASP. NET Core 2 обслуживает запросы api на /api/*
  • ASP. NET Core 2 обслуживает запросы работоспособности на /health
  • ASP. NET Запросы прокси сервера Core 2 на /svc/*
  • ASP. NET Core 2, обслуживающие SPA на /app ИЛИ / (если вы от go до example.com, он будет обслуживать файлы из папки /app/.

Теперь, если кто-то запрашивает сущность, которая не существует, выдается исключение. обрабатывается следующим образом в Startup.cs

app.UseExceptionHandler("/error");

ErrorController обрабатывает эти исключения и возвращает такие вещи, как NotFound(), BadRequest(), et c. В конце , это все ответы JSON.

Теперь, если бы вы перешли на go URL-адрес /hshfdhfgh, это привело бы к пустой странице 404, потому что ничего не соответствует. Но что я хотел бы сделать чтобы иметь возможность добавить несколько пользовательских HTML представлений для страниц с ошибками. Возможно, с помощью Razor Pages или чего-то еще.

Я просмотрел это, и он вам нужен рекомендуется использовать метод UseExceptionHandler("/error"), чтобы вы могли вернуть некоторые представления. Но это противоречило бы моим JSON ответам!

Единственное, что я могу придумать, это что-то вроде:

if request does not start with /health, /svc/, /, /app or /api/
    app.UseExceptionHandler("/error/404");
else
    app.UseExceptionHandler("/error");

Но это кажется очень хакерским. Есть ли другой способ?

И какой был бы лучший / самый простой способ добавить поддержку бритвы в мой проект? в настоящее время его нет.

1 Ответ

0 голосов
/ 10 июля 2020

Вы можете использовать это как начало (это netcore 3.1, но я не думаю, что нам пришлось вносить существенные изменения при переходе с 2). Это кажется хакерским, и больно правильно настроить сам обработчик и поместить его в нужное место в Startup (особенно если вы объедините его с такими вещами, как правильная работа с несанкционированными ответами, просмотры бритвы и файлы stati c для этой бритвы Просмотры). Но я не нашел лучшего способа.

public static readonly PathString ApiPath = new PathString("/api");
public static readonly PathString StaticFilePath = new PathString("/site");
static bool IsApiRequestPredicate(HttpContext context) => context.Request.Path.StartsWithSegments(ApiPath, StringComparison.InvariantCulture);
static bool IsStaticFilePredicate(HttpContext context) => context.Request.Path.StartsWithSegments(StaticFilePath, StringComparison.InvariantCulture);

...

app.UseWhen(x => !IsApiRequestPredicate(x) && !IsStaticFilePredicate(x), builder =>
{
    builder.UseStatusCodePagesWithReExecute("/Error/StatusCodeViewReexecuteHandler/{0}");
    app.UseDeveloperExceptionPage();
});
app.UseWhen(x => IsApiRequestPredicate(x), builder =>
{
    builder.UseExceptionHandler("/Error/ExceptionApiReexecuteHandler");
    builder.UseStatusCodePagesWithReExecute("/Error/StatusCodeApiReexecuteHandler/{0}");
});

Вы также можете использовать только один обработчик и принимать решение на основе OriginalPath в действии ErrorController:

var errorFeature = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerFeature>();
if (errorFeature.OriginalPath.StartsWith("/api", StringComparison.InvariantCulture))
{
    return BadRequest(new { error = "entity not found" });
} else {
    return View("NotFound");
}
// exceptionFeature gives you access to the exception thrown
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...