Смущает обработка ошибок в ASP.net 5 MVC 6

Я хотел бы иметь 1 страницу ошибки, которая в зависимости от предоставленной строки запроса отображает немного другое сообщение об ошибке для пользователя.

Я заметил следующий код в файле Startup.cs при создании нового проекта asp.net 5.

if (env.IsDevelopment())
{
    app.UseBrowserLink();
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}

Мне удалось получить это для отображения правильной страницы ошибки, когда происходит исключение. Моя проблема в том, что он, кажется, только перехватывает ошибки, которые не были обработаны в моем приложении, т.е. всегда с кодом состояния 500, Это правильно?

Обрабатывать 404 ошибки я использую следующий код:

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

С моим контроллером реализовано так:

[HttpGet("{statusCode}")]
public IActionResult Error(int statusCode)
{
    return View(statusCode);
}

Это, кажется, поймать 404 ошибки и отображает правильный код состояния.

Если я обновлю свой код в приведенном выше операторе if, чтобы использовать то же действие, например:

if (env.IsDevelopment())
{
    app.UseBrowserLink();
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error/{0}");
}

Возвращенный код состояния всегда равен 0.

Кроме того, что произойдет, когда 400, 403 или любое другое происходит? Будут ли они пойманы? Если да, то в какой момент они будут пойманы?

Как вы можете заметить, я очень запутался и хотел бы, чтобы кто-нибудь представил мне пример, где обрабатываются все различные коды состояния.

1 ответ

Решение

Похоже, вы путаете необработанные исключения (которые по умолчанию возвращаются клиенту как внутренняя ошибка сервера HTTP 500) и правильно обрабатываются случаи ошибок, вызванные недопустимым действием от имени пользователя / клиента (где HTTP 4xx код возвращается пользователю).

Только первый из них имеет какое-либо отношение к вызову UseExceptionHandler - по умолчанию он будет перехватывать любые необработанные исключения и направлять их к тому, что вы предоставляете (в вашем случае, к представлению, но это может быть просто кусок кода, который проверяет необработанные исключения для преобразования определенных случаев ошибок в коды возврата HTTP 4xx - например, ошибки аутентификации в ответы HTTP 401).

UseStatusCodePagesWithReExecute будет входить туда, где был сгенерирован код состояния 400-599, при условии, что тело ответа еще не было сгенерировано. Рассматриваемый исходный код показывает, как это определяется.

Во втором блоке кода вы использовали UseExceptionHandler - я думаю, у вас должно быть следующее:

if (env.IsDevelopment())
{
    app.UseBrowserLink();
    app.UseDeveloperExceptionPage();
}
else
{
    // Handle unhandled errors
    app.UseExceptionHandler("/Home/Error");
    // Display friendly error pages for any non-success case
    // This will handle any situation where a status code is >= 400
    // and < 600, so long as no response body has already been
    // generated.
    app.UseStatusCodePagesWithReExecute("/Error/{0}"); 
}
Другие вопросы по тегам