Si se le da la ruta:
{FeedName} / {ItemPermalink}
ej .: / Blog / Hello-World
Si el artículo no existe, quiero devolver un 404. ¿Cuál es la forma correcta de hacer esto en ASP.NET MVC?
asp.net
asp.net-mvc
http-status-code-404
Daniel Schaffer
fuente
fuente
Respuestas:
Disparando desde la cadera (codificación de vaquero ;-)), sugeriría algo como esto:
Controlador:
HttpNotFoundResult:
Con este enfoque, cumple con los estándares del marco. Ya hay un HttpUnauthorizedResult allí, por lo que esto simplemente ampliaría el marco a los ojos de otro desarrollador que mantendrá su código más adelante (ya sabe, el psicópata que sabe dónde vive).
Podría usar reflector para echar un vistazo al ensamblaje y ver cómo se logra HttpUnauthorizedResult, porque no sé si este enfoque pierde algo (casi parece demasiado simple).
Usé reflector para echar un vistazo al HttpUnauthorizedResult en este momento. Parece que están configurando el StatusCode en la respuesta a 0x191 (401). Aunque esto funciona para 401, usando 404 como el nuevo valor, parece que obtengo solo una página en blanco en Firefox. Sin embargo, Internet Explorer muestra un 404 predeterminado (no la versión ASP.NET). Usando la barra de herramientas del desarrollador web, inspeccioné los encabezados en FF, que SÍ muestran una respuesta 404 No encontrado. Podría ser simplemente algo que configuré mal en FF.
Dicho esto, creo que el enfoque de Jeff es un buen ejemplo de KISS. Si realmente no necesita la verbosidad en esta muestra, su método también funciona bien.
fuente
Lo hacemos así; este código se encuentra en
BaseController
llamado así
fuente
fuente
web.config
.HttpNotFoundResult es un gran primer paso para lo que estoy usando. Devolver un HttpNotFoundResult es bueno. Entonces la pregunta es, ¿qué sigue?
Creé un filtro de acción llamado HandleNotFoundAttribute que luego muestra una página de error 404. Dado que devuelve una vista, puede crear una vista 404 especial por controlador, o dejar que use una vista 404 compartida predeterminada. Esto incluso se llamará cuando un controlador no tenga la acción especificada presente, porque el marco arroja una HttpException con un código de estado de 404.
fuente
Tenga en cuenta que a partir de MVC3, solo puede usar
HttpStatusCodeResult
.fuente
HttpNotFoundResult
El uso de ActionFilter es difícil de mantener porque cada vez que arrojamos un error, el filtro debe establecerse en el atributo. ¿Qué pasa si nos olvidamos de configurarlo? Una forma es derivar
OnException
en el controlador base. Debe definir unBaseController
derivado deController
y todos los controladores deben derivar deBaseController
. Es una buena práctica tener un controlador base.Tenga en cuenta que si
Exception
el código de estado de respuesta es 500, debemos cambiarlo a 404 para No encontrado y 401 para No autorizado. Como mencioné anteriormente, useOnException
anulacionesBaseController
para evitar usar el atributo de filtro.El nuevo MVC 3 también hace más problemático al devolver una vista vacía al navegador. La mejor solución después de algunas investigaciones se basa en mi respuesta aquí. ¿Cómo devolver una vista para HttpNotFound () en ASP.Net MVC 3?
Para hacer más conveniencia lo pego aquí:
Después de un poco de estudio. La solución para MVC 3 aquí es derivar todos
HttpNotFoundResult
,HttpUnauthorizedResult
,HttpStatusCodeResult
clases e implementar nueva (anulando ella)HttpNotFound
método () enBaseController
.Es una buena práctica utilizar el controlador base para que tenga "control" sobre todos los controladores derivados.
Creo una nueva
HttpStatusCodeResult
clase, no para derivarActionResult
sino desdeViewResult
para representar la vista o cualquieraView
que desee especificando laViewName
propiedad. Sigo el originalHttpStatusCodeResult
para establecer elHttpContext.Response.StatusCode
y,HttpContext.Response.StatusDescription
pero luegobase.ExecuteResult(context)
renderizaré la vista adecuada porque de nuevo derivaré deViewResult
. ¿Es bastante simple? Espero que esto se implemente en el núcleo MVC.Mira mi
BaseController
bramido:Para usar en su acción de esta manera:
Y en _Layout.cshtml (como página maestra)
Además, puede usar una vista personalizada como
Error.shtml
o crear una nuevaNotFound.cshtml
como comenté en el código y puede definir un modelo de vista para la descripción del estado y otras explicaciones.fuente