Смущает обработка ошибок в 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}");
}