По умолчанию все ответы, созданные с помощью StatusCodeResult и метода контроллера StatusCode(…) возвращают обычный HTTP ответ с кодом статуса. Однако ASP.NET MVC Core позволяет создать контроллер для генерации ответов для HTTP кодов ошибок (от 400 до 599) так, как это необходимо разработчику. Например, чтобы все ответы были в одинаковом формате. Посмотрим как это можно сделать. |
Создание контроллера
Описанный ниже способ не перехватывает ответы с кодом ошибки, которые
- были вызваны исключениями
- или содержат тело с данными
В ASP.NET MVC Core проект добавим новый контроллер. Для примера, назовем его StatusCodeController. В нем будет расположено одно действие Index, которое будет отвечать за создание ответа со статусом.
public class StatusCodesController : Controller
{
public IActionResult Index(int statusCode)
{
var feature = this.HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
// Логика обработки. Для примера просто вернем страницу выводящую HTTP код.
return View(statusCode);
}
}
Имена контроллера, метода (действия) и параметра могут быть любыми. Позже они будут указаны в конфигурации.
Параметр statusCode, как можно легко догадаться, получит значения HTTP кода.
Стоит обратить внимание на переменную feature. В нее будет передан экземпляр объекта, содержащий следующие свойства, которые могут пригодиться в логике контроллера:
- OriginalPathBase – исходный базовый путь.
- OriginalPath – исходный путь.
- OriginalQueryString – исходная строка запроса.
Регистрация контроллера
Если сейчас запустить проект и в каком-то из контроллеров вернуть HTTP код 400 или выше, то ничего нового не произойдет. Все дело в том, что необходимо зарегистрировать контроллер в качестве ответственного за возврат HTTP кодов статуса. Для этого в классе StartUp необходимо вызвать один из двух методов:
- UseStatusCodePagesWithReExecute(this IApplicationBuilder app, string pathFormat, string queryFormat = null) – указывает адрес, которые ответственный за создание ответа. По сути конвейер приложения будет перезапущен для нового адреса. Клиент получит ответ сразу по завершению его работы. При этом, например, адрес в строке браузера не изменится.
- UseStatusCodePagesWithRedirects(this IApplicationBuilder app, string pathFormat) – сделает переадресацию на указанный адрес. Клиент должен перейти по нему, чтобы получить ответ. При этом, например, адрес в строке браузера изменится на новый.
В переменной pathFormat допускается использование строки “{0}” которая будет заменена на значение HTTP кода.
Например, регистрация контроллера, созданного выше, будет выглядеть следующим образом:
public class Startup
{
...
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseStatusCodePagesWithReExecute("/StatusCodes/Index", "?statusCode={0}");
// или
app.UseStatusCodePagesWithRedirects("StatusCodes/Index?statusCode={0}");
...
}
}
Вот теперь можно запустить приложение, обратиться к контроллеру, действие которого вернет например StatusCode(400) и убедиться в работоспособности StatusCodeController. Например:
public class HomeController : Controller
{
public IActionResult Index()
{
return StatusCode(400);
}
}