Estoy usando RC2
Uso de enrutamiento de URL:
routes.MapRoute(
"Error",
"{*url}",
new { controller = "Errors", action = "NotFound" } // 404s
);
Lo anterior parece ocuparse de solicitudes como esta (suponiendo que las tablas de ruta predeterminadas estén configuradas por el proyecto MVC inicial): "/ blah / blah / blah / blah"
Anulación de HandleUnknownAction () en el controlador en sí:
// 404s - handle here (bad action requested
protected override void HandleUnknownAction(string actionName) {
ViewData["actionName"] = actionName;
View("NotFound").ExecuteResult(this.ControllerContext);
}
Sin embargo, las estrategias anteriores no manejan una solicitud a un controlador incorrecto / desconocido. Por ejemplo, no tengo un "/ IDoNotExist", si lo solicito, obtengo la página genérica 404 del servidor web y no mi 404 si uso enrutamiento + anulación.
Entonces, finalmente, mi pregunta es: ¿hay alguna forma de atrapar este tipo de solicitud utilizando una ruta u otra cosa en el marco MVC?
¿O debería simplemente usar Web.Config customErrors como mi controlador 404 y olvidar todo esto? Supongo que si voy con customErrors tendré que almacenar la página 404 genérica fuera de / Vistas debido a las restricciones de Web.Config en el acceso directo.
Respuestas:
El código está tomado de http://blogs.microsoft.co.il/blogs/shay/archive/2009/03/06/real-world-error-hadnling-in-asp-net-mvc-rc2.aspx y funciona en ASP.net MVC 1.0 también
Así es como manejo las excepciones http:
fuente
Requisitos para 404
Los siguientes son mis requisitos para una solución 404 y a continuación muestro cómo lo implemento:
Solución
Creo que debería ahorrar
Application_Error
en Global.asax para cosas más altas, como excepciones y registros no controlados (como muestra la respuesta de Shay Jacoby ) pero no manejo 404. Es por eso que mi sugerencia mantiene las cosas 404 fuera del archivo Global.asax.Paso 1: tenga un lugar común para la lógica de error 404
Esta es una buena idea para la mantenibilidad. Utilice un ErrorController para que las futuras mejoras a su página 404 bien diseñada puedan adaptarse fácilmente. Además, ¡ asegúrese de que su respuesta tenga el código 404 !
Paso 2: utilice una clase de controlador base para que pueda invocar fácilmente su acción 404 personalizada y conectarse
HandleUnknownAction
Los 404 en ASP.NET MVC deben capturarse en varios lugares. La primera es
HandleUnknownAction
.El
InvokeHttp404
método crea un lugar común para redirigir aErrorController
nuestra nuevaHttp404
acción. Piensa SECO !Paso 3: use la inyección de dependencia en su fábrica de controladores y conecte 404 HttpExceptions
Así (no tiene que ser StructureMap):
MVC1.0 ejemplo:
MVC2.0 ejemplo:
Creo que es mejor detectar los errores más cerca de donde se originan. Es por eso que prefiero lo anterior al
Application_Error
controlador.Este es el segundo lugar para atrapar 404s.
Paso 4: agregue una ruta NotFound a Global.asax para las URL que no se analizan en su aplicación
Esta ruta debe apuntar a nuestra
Http404
acción. ¿Teurl
das cuenta de que el parámetro será una URL relativa porque el motor de enrutamiento está quitando la parte del dominio aquí? Es por eso que tenemos toda esa lógica de URL condicional en el Paso 1.Este es el tercer y último lugar para atrapar 404 en una aplicación MVC que no invocas tú mismo. Si no detecta rutas inigualables aquí, MVC pasará el problema a ASP.NET (Global.asax) y realmente no quiere eso en esta situación.
Paso 5: finalmente, invoque 404s cuando su aplicación no pueda encontrar algo
Como cuando se envía una identificación incorrecta a mi controlador de préstamos (deriva de
MyController
):Sería bueno si todo esto se pudiera conectar en menos lugares con menos código, pero creo que esta solución es más fácil de mantener, más comprobable y bastante pragmática.
Gracias por los comentarios hasta ahora. Me encantaría tener más.
NOTA: Esto ha sido editado significativamente de mi respuesta original pero el propósito / requisitos son los mismos, es por eso que no he agregado una nueva respuesta
fuente
customErrors
sección de web.config define páginas de redireccionamiento estático que se manejan a un alto nivel en aspnet, si no en IIS. Esto no es lo que quería, ya que necesitaba que el resultado fuera MVC Views (para que pueda tener datos en ellos, etc.). No diría categóricamente que "customErrors
está obsoleto en MVC", pero para mí y para esta solución 404 ciertamente lo son.ObjectFactory.GetInstance
cambié a MVC3,DependencyResolver.Current.GetService
así que es más genérico. Estoy usando Ninject.ASP.NET MVC no admite páginas 404 personalizadas muy bien. Fábrica de controladores personalizados, ruta general, clase de controlador base con
HandleUnknownAction
- ¡argh!Las páginas de error personalizadas de IIS son una mejor alternativa hasta ahora:
web.config
ErrorController
Proyecto de muestra
fuente
customErrors mode="On"
junto con elHandleErrorAttribute
ser funcional. Las páginas de error personalizadas para excepciones no controladas en acciones del controlador ya no se sirven.Respuesta rápida / TL; DR
Para la gente perezosa por ahí:
Luego elimine esta línea de
global.asax
Y esto es solo para IIS7 + e IIS Express.
Si estás usando Cassini ... bueno ... um ... er ... incómodo ...
Respuesta larga y explicada
Sé que esto ha sido respondido. Pero la respuesta es REALMENTE SIMPLE (aplausos para David Fowler y Damian Edwards por responder realmente esto).
No hay necesidad de hacer nada personalizado .
Para
ASP.NET MVC3
, todos los pedazos están ahí.Paso 1 -> Actualiza tu web.config en DOS lugares.
y
Ahora tome nota de las RUTAS que he decidido utilizar. Puedes usar cualquier cosa, pero mis rutas son
/NotFound
<- para un 404 no encontrado, página de error./ServerError
<- para cualquier otro error, incluya los errores que suceden en mi código. este es un error interno del servidor 500¿Ves cómo la primera sección
<system.web>
solo tiene una entrada personalizada? LastatusCode="404"
entrada? Solo he enumerado un código de estado porque todos los demás errores, incluido el500 Server Error
(es decir, esos molestos errores que ocurren cuando su código tiene un error y bloquea la solicitud del usuario) ... todos los otros errores son manejados por la configuracióndefaultRedirect="/ServerError"
... que dice , si no se encuentra una página 404, vaya a la ruta/ServerError
.Okay. eso está fuera del camino ... ahora a mis rutas enumeradas en
global.asax
Paso 2: crear las rutas en Global.asax
Aquí está mi sección de ruta completa ...
Eso enumera dos rutas de ignorar ->
axd's
yfavicons
(¡ooo! Bonus ignora la ruta, ¡para ti!) Luego (y el pedido es IMPERATIVO AQUÍ), tengo mis dos rutas explícitas de manejo de errores ... seguidas de cualquier otra ruta. En este caso, el predeterminado. Por supuesto, tengo más, pero eso es especial para mi sitio web. Solo asegúrese de que las rutas de error estén en la parte superior de la lista. El orden es imperativo .Finalmente, mientras estamos dentro de nuestro
global.asax
archivo, NO registramos globalmente el atributo HandleError. No, no, no señor. Nadda No Nien Negativo. Noooooooooo ...Eliminar esta línea de
global.asax
Paso 3: crea el controlador con los métodos de acción
Ahora ... agregamos un controlador con dos métodos de acción ...
Ok, veamos esto. En primer lugar, NO hay
[HandleError]
atributo aquí. ¿Por qué? Debido a que elASP.NET
marco integrado ya está manejando errores Y hemos especificado toda la mierda que debemos hacer para manejar un error :) ¡Está en este método!A continuación, tengo los dos métodos de acción. Nada duro allí. Si desea mostrar alguna información de excepción, puede usarla
Server.GetLastError()
para obtener esa información.Bonificación WTF: Sí, hice un tercer método de acción, para probar el manejo de errores.
Paso 4: crea las vistas
Y finalmente, crea dos vistas. Póngalos en el punto de vista normal, para este controlador.
Comentarios adicionales
Application_Error(object sender, EventArgs e)
Y eso, mis amigos, debería ser.
¡Ahora, felicidades por leer tanto y tener un Unicornio como premio!
fuente
?aspxerrorpath=/er/not/found
tener en URL.He investigado MUCHO sobre cómo administrar adecuadamente los 404 en MVC (específicamente MVC3) , y esta, en mi humilde opinión, es la mejor solución que he encontrado:
En global.asax:
Errores Controlador:
(Opcional)
Explicación:
AFAIK, hay 6 casos diferentes que una aplicación ASP.NET MVC3 puede generar 404.
(Generado automáticamente por ASP.NET Framework :)
(1) Una URL no encuentra una coincidencia en la tabla de rutas.
(Generado automáticamente por ASP.NET MVC Framework :)
(2) Una URL encuentra una coincidencia en la tabla de rutas, pero especifica un controlador inexistente.
(3) Una URL encuentra una coincidencia en la tabla de rutas, pero especifica una acción no existente.
(Generado manualmente :)
(4) Una acción devuelve un HttpNotFoundResult utilizando el método HttpNotFound ().
(5) Una acción arroja una HttpException con el código de estado 404.
(6) Una acción modifica manualmente la propiedad Response.StatusCode a 404.
Normalmente, quieres lograr 3 objetivos:
(1) Mostrar una página de error 404 personalizada al usuario.
(2) Mantener el código de estado 404 en la respuesta del cliente (especialmente importante para SEO).
(3) Enviar la respuesta directamente, sin involucrar una redirección 302.
Hay varias formas de tratar de lograr esto:
(1)
Problemas con esta solución:
(2)
Problemas con esta solución:
(3)
Problemas con esta solución:
(4)
y
Problemas con esta solución:
Las personas que han tenido problemas con esto antes incluso intentaron crear sus propias bibliotecas (consulte http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html ). Pero la solución anterior parece cubrir todos los casos sin la complejidad de usar una biblioteca externa.
fuente
public ActionResult NotFound() {}
en tu ErrorController. Además, ¿puede explicar cómo_NotFound
se vería su parcial para las solicitudes AJAX?MissingMethodException: Cannot create an abstract class
en línea ¿c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
Alguna idea?Realmente me gusta la solución cottsaks y creo que se explica muy claramente. mi única adición fue alterar el paso 2 de la siguiente manera
Básicamente, esto evita que las URL que contienen acciones no válidas Y los controladores activen la rutina de excepción dos veces. por ejemplo, para URL como asdfsdf / dfgdfgd
fuente
La única forma en que podía hacer que el método de @ cottsak funcionara para controladores no válidos era modificar la solicitud de ruta existente en CustomControllerFactory, de esta manera:
Debo mencionar que estoy usando MVC 2.0.
fuente
Aquí hay otro método que utiliza herramientas MVC que puede manejar solicitudes de nombres de controlador incorrectos, nombres de ruta incorrectos y cualquier otro criterio que considere adecuado dentro de un método de Acción. Personalmente, prefiero evitar tantas configuraciones web.config como sea posible, ya que hacen la redirección 302/200 y no admiten ResponseRewrite (
Server.Transfer
) usando las vistas Razor. Prefiero devolver un 404 con una página de error personalizada por razones de SEO.Algo de esto es una nueva versión de la técnica de Cottsak anterior.
Esta solución también utiliza una configuración mínima de web.config que favorece los filtros de error MVC 3.
Uso
Simplemente arroje una HttpException desde una acción o ActionFilterAttribute personalizado.
Paso 1
Agregue la siguiente configuración a su web.config. Esto es necesario para usar HandleErrorAttribute de MVC.
Paso 2
Agregue un HandleHttpErrorAttribute personalizado similar al HandleErrorAttribute del marco MVC, a excepción de los errores HTTP:
Paso 3
Agregue filtros a GlobalFilterCollection (
GlobalFilters.Filters
) enGlobal.asax
. Este ejemplo enrutará todos los errores de InternalServerError (500) a la vista compartida Error (Views/Shared/Error.vbhtml
). Los errores NotFound (404) se enviarán también a ErrorHttp404.vbhtml en las vistas compartidas. He agregado un error 401 aquí para mostrarle cómo se puede extender esto para códigos de error HTTP adicionales. Tenga en cuenta que estas deben ser vistas compartidas, y todas usan elSystem.Web.Mvc.HandleErrorInfo
objeto como modelo.Paso 4
Cree una clase de controlador base y herede de ella en sus controladores. Este paso nos permite manejar nombres de acciones desconocidos y elevar el error HTTP 404 a nuestro HandleHttpErrorAttribute.
Paso 5
Cree una anulación ControllerFactory y anúlela en su archivo Global.asax en Application_Start. Este paso nos permite generar la excepción HTTP 404 cuando se ha especificado un nombre de controlador no válido.
Paso 6
Incluya una ruta especial en su RoutTable.Routes para la acción Desconocida de BaseController. Esto nos ayudará a generar un 404 en el caso de que un usuario acceda a un controlador desconocido o acción desconocida.
Resumen
Este ejemplo demostró cómo se puede usar el marco MVC para devolver códigos de error 404 Http al navegador sin una redirección utilizando atributos de filtro y vistas de error compartidas. También demuestra que muestra la misma página de error personalizada cuando se especifican nombres de controlador y nombres de acción no válidos.
Agregaré una captura de pantalla de un nombre de controlador no válido, un nombre de acción y un 404 personalizado generado desde la acción Inicio / TriggerNotFound si obtengo suficientes votos para publicar uno =). Fiddler devuelve un mensaje 404 cuando accedo a las siguientes URL con esta solución:
La publicación de Cottsak anterior y estos artículos fueron buenas referencias.
fuente
The IControllerFactory 'aaa.bbb.CustomControllerFactory' did not return a controller for the name '123'.
¿alguna idea de por qué iba a conseguir eso?Mi solución abreviada que funciona con áreas no controladas, controladores y acciones:
Cree una vista 404.cshtml.
Cree una clase base para sus controladores:
Cree una fábrica de controladores personalizados que devuelva su controlador base como respaldo:
Agregue a
Application_Start()
la siguiente línea:fuente
En MVC4 WebAPI 404 se puede manejar de la siguiente manera,
CURSOS APICONTROLADOR
CONTROLADOR DEL HOGAR
VER
GLOBAL
RESULTADOS
fuente
Prueba NotFoundMVC en nuget. Funciona, sin configuración.
fuente
http://localhost/Views/Shared/NotFound.cshtml
no da como resultado una página 404 personalizada.Mi solución, en caso de que alguien lo encuentre útil.
En Web.config:
En
Controllers/ErrorController.cs
:Agregue un
PageNotFound.cshtml
en laShared
carpeta, y eso es todo.fuente
model.RequestedUrl = Request.Url.OriginalString.Contains(url) & Request.Url.OriginalString != url ? Request.Url.OriginalString : url;
y nomodel.RequestedUrl = Request.Url.OriginalString.Contains(url) && Request.Url.OriginalString != url ? Request.Url.OriginalString : url;
(y en lugar de &&)?Sin embargo, me parece que la
CustomErrors
configuración estándar debería funcionar , debido a la dependencia deServer.Transfer
que parece que la implementación interna deResponseRewrite
no es compatible con MVC.Esto se siente como un agujero de funcionalidad deslumbrante para mí, así que decidí volver a implementar esta característica usando un módulo HTTP. La solución a continuación le permite manejar cualquier código de estado HTTP (incluido 404) al redirigir a cualquier ruta MVC válida como lo haría normalmente.
Esto ha sido probado en las siguientes plataformas;
Beneficios
La solución
Uso
Incluya esto como el último módulo HTTP en su web.config
Para aquellos de ustedes que estén prestando atención, notarán que en el modo Integrated Pipeline esto siempre responderá con HTTP 200 debido a la forma en que
Server.TransferRequest
funciona. Para devolver el código de error adecuado, uso el siguiente controlador de error.fuente
Tratar los errores en ASP.NET MVC es solo una molestia. Intenté muchas sugerencias en esta página y en otras preguntas y sitios, y nada funciona bien. Una sugerencia fue manejar errores en web.config dentro de system.webserver pero eso solo devuelve páginas en blanco .
Mi objetivo al encontrar esta solución era;
Aquí está mi solución.
1. Agregue lo siguiente a la sección system.web
Lo anterior maneja cualquier URL no manejada por routes.config y excepciones no manejadas, especialmente aquellas encontradas en las vistas. Tenga en cuenta que usé aspx, no html . Esto es para que pueda agregar un código de respuesta en el código detrás.
2 . Cree una carpeta llamada Error (o lo que prefiera) en la raíz de su proyecto y agregue los dos formularios web. Debajo está mi página 404;
Y en el código detrás establecí el código de respuesta
Haz lo mismo para la página 500
3. Para manejar errores dentro de los controladores. Hay muchas formas de hacerlo. Esto es lo que funcionó para mí. Todos mis controladores heredan de un controlador base. En el controlador base, tengo los siguientes métodos
4. Agregue CustomError.cshtml a su carpeta Vistas compartidas . Debajo está el mío;
Ahora en su controlador de aplicación puede hacer algo como esto;
Ahora para la advertencia . No manejará errores de archivos estáticos. Entonces, si tiene una ruta como example.com/widgets y el usuario la cambia a example.com/widgets.html , obtendrá la página de error predeterminada de IIS, por lo que debe manejar los errores de nivel de IIS de otra manera.
fuente
Publicando una respuesta ya que mi comentario fue demasiado largo ...
Es tanto un comentario como preguntas para la publicación / respuesta del unicornio:
https://stackoverflow.com/a/7499406/687549
Prefiero esta respuesta sobre las otras por su simplicidad y el hecho de que aparentemente se consultó a algunas personas en Microsoft. Sin embargo, obtuve tres preguntas y si pueden responderse, llamaré a esta respuesta el santo grial de todas las respuestas de error 404/500 en las interwebs para una aplicación ASP.NET MVC (x).
@ Pure.Krome
¿Puede actualizar su respuesta con el material de SEO de los comentarios señalados por GWB (nunca se mencionó esto en su respuesta)
<customErrors mode="On" redirectMode="ResponseRewrite">
y<httpErrors errorMode="Custom" existingResponse="Replace">
?¿Pueden preguntarle a sus amigos del equipo ASP.NET si está bien hacerlo así? Sería bueno tener alguna confirmación. ¿Tal vez sea un gran no-no cambiar
redirectMode
yexistingResponse
de esta manera poder jugar bien con SEO?Se puede añadir algunas aclaraciones que rodea todo eso (
customErrors redirectMode="ResponseRewrite"
,customErrors redirectMode="ResponseRedirect"
,httpErrors errorMode="Custom" existingResponse="Replace"
, ELIMINARcustomErrors
TOTALMENTE como alguien sugirió) después de hablar con sus amigos en Microsoft?Como decía; Sería estupendo si pudiéramos hacer que su respuesta sea más completa, ya que esta parece ser una pregunta bastante popular con más de 54 000 visitas.
Actualización : La respuesta de Unicornio hace un 302 encontrado y un 200 OK y no se puede cambiar para que solo devuelva 404 usando una ruta. Tiene que ser un archivo físico que no sea muy MVC: ish. Entonces, pasar a otra solución. Lástima porque este parecía ser el MVC definitivo: esta es la respuesta hasta ahora.
fuente
Agregué mi solución, que es casi idéntica a la de Herman Kan, con una pequeña arruga para que funcione para mi proyecto.
Cree un controlador de error personalizado:
Luego cree una fábrica de controladores personalizados:
Finalmente, agregue una anulación al controlador de error personalizado:
Y eso es. No es necesario realizar cambios en Web.config.
fuente
1) Hacer una clase abstracta de controlador.
2) Haga la herencia de esta clase abstracta en todos sus controladores
3) Y agregue una vista llamada "NotFound" en su carpeta View-Shared.
fuente
Revisé la mayoría de las soluciones publicadas en este hilo. Si bien esta pregunta puede ser antigua, aún es muy aplicable a nuevos proyectos, incluso ahora, por lo que pasé mucho tiempo leyendo las respuestas presentadas aquí y en otros lugares.
Como @Marco señaló los diferentes casos bajo los cuales puede ocurrir un 404, verifiqué la solución que compilé en esa lista. Además de su lista de requisitos, también agregué uno más.
Esta solución es doble:
La primera parte proviene de @Guillaume en https://stackoverflow.com/a/27354140/2310818 . Su solución se encarga de cualquier 404 causado por una ruta no válida, un controlador no válido y una acción no válida.
La idea es crear un formulario web y luego hacer que llame a la acción NotFound de su controlador de errores MVC. Hace todo esto sin ningún redireccionamiento, por lo que no verá un solo 302 en Fiddler. La URL original también se conserva, lo que hace que esta solución sea fantástica.
La segunda parte proviene de @ Germán en https://stackoverflow.com/a/5536676/2310818 . ¡Su solución se encarga de cualquier 404 devuelto por sus acciones en forma de HttpNotFoundResult () o arroja una nueva HttpException ()!
La idea es tener un filtro que mire la respuesta, así como la excepción lanzada por sus controladores MVC y llamar a la acción apropiada en su controlador de errores. De nuevo, esta solución funciona sin redireccionamiento y se conserva la URL original.
Como puede ver, ambas soluciones juntas ofrecen un mecanismo de manejo de errores muy robusto y cumplen todos los requisitos enumerados por @Marco, así como mis requisitos. Si desea ver una muestra de trabajo o una demostración de esta solución, por favor deje en los comentarios y me complacería reunirla.
fuente
He revisado todos los artículos, pero nada funciona para mí: mi usuario de requisito debe escribir algo en su página 404 personalizada de URL debe mostrar. Pensé que es muy sencillo. Pero debe comprender el manejo del 404 correctamente:
Este artículo me pareció muy útil. Debería leerlo de inmediato. Página de error de Custome-Ben Foster
fuente