ASP.NET MVC 6 maneja errores basados ​​en el código de estado HTTP

Quiero mostrar diferentes mensajes de error para cada código de estado, por ejemplo:

  • 400 Petición Incorrecta
  • 403 Prohibido
  • Error interno de servidor 500
  • 404 No encontrado
  • 401 no autorizado

¿Cómo puedo lograr esto en las nuevas aplicaciones ASP.NET MVC 6? ¿Puedo hacer esto usando el método integrado en UseErrorHandler?

application.UseErrorHandler("/error"); 

Además, me di cuenta de que, incluso con el controlador anterior, al ingresar una URL inexistente, por ejemplo, / esta página no existe, se genera una página de error 404 No encontrado del IIS. ¿Cómo se puede manejar esto también?

En MVC 5 hemos tenido que usar la sección system.web customerrors para ASP.NET y la sección system.webServer httpErrors en el archivo web.config, pero fue difícil trabajar con un comportamiento difícil de manejar, con muchos comportamientos muy extraños. ¿MVC 6 hace esto mucho más simple?

Podría usar el StatusCodePagesMiddleware para esto. A continuación se muestra un ejemplo:

 public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { app.UseStatusCodePagesWithReExecute("/StatusCodes/StatusCode{0}"); app.UseMvcWithDefaultRoute(); 

Controlador que maneja las solicitudes de código de estado:

 public class StatusCodesController : Controller { public IActionResult StatusCode404() { return View(viewName: "NotFound"); // you have a view called NotFound.cshtml } ... more actions here to handle other status codes } 

Algunas notas:

  • Verifique otros métodos de extensión como UseStatusCodePagesWithRedirects y UseStatusCodePages para otras capacidades.
  • Intenté tener StatusCode como una cadena de consulta en mi ejemplo, pero parece que este middleware no maneja cadenas de consulta, pero puedes echar un vistazo a este código y solucionar este problema.

¿Cómo puedo lograr esto en las nuevas aplicaciones ASP.NET MVC 6? ¿Puedo hacer esto usando el método integrado en UseErrorHandler?

Respuesta rápida: No de una manera elegante.

Explicación / Alternativa: Para comenzar, veamos primero lo que realmente está haciendo el método UseErrorHandler : https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83gunas de las UseErrorHandler las UseErrorHandler las UseErrorHandler las UseErrorHandler la UseErrorHandler siguiente middleware: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6e7259de81f83a04d1654170137/src/Microsoft.AspNet.Diagnostics/ErrorHandlerMiddleware.cs Líneas de nota 29-78 (invoca)

El método de invocación se ejecuta siempre que llega una solicitud (controlada por la ubicación de su application.UseErrorHandler("...") . Startup.cs application.UseErrorHandler("...") en su Startup.cs ). Por lo tanto, UseErrorHandler es una forma glorificada de agregar un middleware personalizado: middleware = componente que puede actuar en una solicitud http.

Ahora con ese fondo, si quisiéramos agregar nuestro propio middleware de error que diferencie las solicitudes. Podríamos hacer esto agregando un middleware similar que es como el ErrorHandlerMiddleware predeterminado modificando estas líneas: https://github.com/aspnet/Diagnostics/blob/6dbbe831c493e6Eas ErrorHandlerMiddleware de las ErrorHandlerMiddleware de las ErrorHandlerMiddleware de la ErrorHandlerMiddleware . Con ese enfoque podríamos controlar la ruta de redirección basada en el código de estado.

En MVC 5 hemos tenido que usar la sección system.web customerrors para ASP.NET y la sección system.webServer httpErrors en el archivo web.config, pero fue difícil trabajar con un comportamiento difícil de manejar, con muchos comportamientos muy extraños. ¿MVC 6 hace esto mucho más simple?

Respuesta: Seguro que sí :). Al igual que la respuesta anterior, la solución está en agregar middleware. Hay un atajo para agregar middleware simple a través de IApplicationBuilder en su Startup.cs ; al final de su método de Configure puede agregar lo siguiente:

 app.Run(async (context) => { await context.Response.WriteAsync("Could not handle the request."); // Nothing else will run after this middleware. }); 

Esto funcionará porque significa que llegó al final de su canalización http sin que se manejara la solicitud (ya que se encuentra al final de su método de Configure en Startup.cs ). Si desea agregar este middleware (de manera rápida) con la opción de ejecutar middleware después de usted, a continuación le indicamos cómo:

 app.Use(async (context, next) => { await context.Response.WriteAsync("Could not handle the request."); // This ensures that any other middelware added after you runs. await next(); }); 

¡Espero que esto ayude!

Funciona con varios códigos de estado sin especificar cada uno individualmente en el controlador.

Startup.cs:

 public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { app.UseStatusCodePagesWithRedirects("/StatusCodes?statusCode={0}"); app.UseMvcWithDefaultRoute(); 

Controlador:

  public class StatusCodesController : Controller { public IActionResult Index(string statusCode) { if(statusCode == null) statusCode = ""; if(statusCode == "404") return View("Error404"); return View("Index",statusCode); } public IActionResult Test404() { return StatusCode(404); } public IActionResult Test500() { return StatusCode(500); } 

Ver:

 @model string @{ ViewData["Title"] = Model + " Oops!"; }  

Oops!

@Model Error

Sorry, an error has occurred!