ASP.NET MVC: captura toda ruta y ruta predeterminada

Al intentar que mi aplicación produzca errores 404 correctamente, he implementado una ruta catch all al final de mi tabla de rutas, como se muestra a continuación:

routes.MapRoute( "NotFound", _ "{*url}", _ New With {.controller = "Error", .action = "PageNotFound"} _ ) 

Sin embargo, para que esto funcione, tuve que eliminar la ruta predeterminada:

 {controller}/action/{id} 

Pero ahora que se eliminó el valor predeterminado, la mayoría de mis enlaces de acción ya no funcionan, y la única forma que he encontrado para que funcionen nuevamente es agregar rutas individuales para cada controlador / acción.

¿Hay una manera más simple de hacer esto, en lugar de agregar una ruta para cada controlador / acción?

¿Es posible crear una ruta predeterminada que aún permita que la ruta catch all funcione si el usuario intenta navegar a una ruta desconocida?

Usar restricciones de ruta

En su caso, debe definir su ruta predeterminada {controller}/{action}/{id} y ponerle una restricción. Probablemente relacionado con los nombres de los controladores o incluso acciones. Luego coloque la captura una detrás de la otra y debería funcionar bien.

Entonces, cuando alguien solicita un recurso que no cumple con una restricción, la ruta catch-all coincidiría con la solicitud.

Asi que. Primero defina su ruta predeterminada con restricciones de ruta y luego atrape todas las rutas después de ella:

 routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new { controller = "Home|Settings|General|..." } // this is basically a regular expression ); routes.MapRoute( "NotFound", "{*url}", new { controller = "Error", action = "PageNotFound" } ); 
 //this catches all requests routes.MapRoute( "Error", "{*.}", new { controller = "PublicDisplay", action = "Error404" } ); 

agregue esta ruta al final de la tabla de rutas

Ah, el problema es que tu ruta predeterminada captura las URL de 3 segmentos . El problema aquí es que el enrutamiento se ejecuta mucho antes de que determinemos quién va a gestionar la solicitud. Por lo tanto, cualquier URL de tres segmentos coincidirá con la ruta predeterminada, incluso si termina más tarde que no hay controlador para manejarla.

Una cosa que puede hacer es en su controlador anular el método HandleMissingAction. También debe usar la etiqueta para detectar todos los problemas 404.

Bueno, lo que encontré es que no hay una buena manera de hacer esto. Establecí la propiedad redirectMode de customErrors en ResponseRewrite .

    

Esto me da el comportamiento buscado, pero no muestra la página formateada.

Para mí, esto está mal hecho, en lo que respecta al SEO. Sin embargo, creo que hay una solución que me falta porque SO hace exactamente lo que quiero que suceda. La URL permanece en la página fallida y arroja un 404. Inspecciona stackoverflow.com/fail en Firebug.

Recomendaría esto como la versión más fácil de leer. Lo necesita en su RouteConfig.cs, y un controlador llamado ErrorController.cs, que contiene una acción ‘PageNotFound’. Esto puede devolver una vista. Cree un PageNotFound.cshtml y se lo devolverá en respuesta al 404:

  routes.MapRoute( name: "PageNotFound", url: "{*url}", defaults: new { controller = "Error", action = "PageNotFound" } ); 

Cómo leer esto:

 name: "PageNotFound" 

= crear una nueva plantilla de ruta, con el nombre arbitrario ‘PageNotFound’

 url:"{*url}" 

= usar esta plantilla para mapear todas las rutas no manejadas

 defaults: new { controller = "Error", action = "PageNotFound" } 

= define la acción a la que se asignará una ruta incorrecta (el método de acción ‘PageNotFound’ en el controlador de errores). Esto es necesario ya que una ruta incorrecta ingresada obviamente no se asignará a ningún método de acción

Probablemente sea mejor configurar el documento de error 404 en la sección de la configuración y luego restaurar la ruta predeterminada.

FWIW, creo que el requisito de ruta predeterminado también se retrasa.

Mi solución es de 2 pasos.

Originalmente resolví este problema agregando esta función a mi archivo Global.asax.cs:

 protected void Application_Error(Object sender, EventArgs e) 

Donde intenté convertir Server.GetLastError () en una HttpException y luego compruebo GetHttpCode. Esta solución se detalla aquí:

Error de manejo personalizado de ASP.NET MVC Application_Error Global.asax?

Esta no es la fuente original donde obtuve el código. Sin embargo, esto solo detecta errores 404 que ya se han enrutado. En mi caso, que mencione cualquier URL de 2 niveles.

por ejemplo, estas URL mostrarían la página 404:

http://www.site.com/blah

http://www.site.com/blah/blah

sin embargo, http://www.site.com/blah/blah/blah simplemente diría que no se pudo encontrar la página. Añadiendo su ruta de captura después de que todas mis otras rutas resolvieron esto:

 routes.MapRoute( "NotFound", "{*url}", new { controller = "Errors", action = "Http404" } ); 

Sin embargo, la ruta NotFound no parece enrutar las solicitudes que tienen extensiones de archivo. Esto funciona cuando son capturados por diferentes rutas.

Si está buscando ASP.NET Core, tome todas las rutas y busque en Google asp.net core catch all route traen aquí:

ASP.NET núcleo MVC atrapar todas las rutas servir archivo estático