Cómo obtener la acción MVC para devolver 404


142

Tengo una acción que toma una cadena que se usa para recuperar algunos datos. Si esta cadena no devuelve datos (tal vez porque se ha eliminado), quiero devolver un 404 y mostrar una página de error.

Actualmente solo uso devolver una vista especial que muestra un mensaje de error descriptivo específico de esta acción que dice que no se encontró el elemento. Esto funciona bien, pero idealmente le gustaría devolver un código de estado 404 para que los motores de búsqueda sepan que este contenido ya no existe y pueden eliminarlo de los resultados de búsqueda.

¿Cuál es la mejor manera de hacer esto?

¿Es tan simple como configurar Response.StatusCode = 404?


también debe mantener Response. TrySkipIisCustomErrors = true; La respuesta de @ganders fue un salvavidas ...
Trueno

Respuestas:


111

Hay múltiples formas de hacerlo,

  1. Tiene razón en el código aspx común, se puede asignar de la manera especificada
  2. throw new HttpException(404, "Some description");

1
Una cosa a tener en cuenta es que si tiene una página de error personalizada configurada para manejar 404, entonces esta página de error devolverá 200 (se encontró la página no encontrada ... :-(). Tiendo a lanzar la excepción de decir BlogController y que la acción NotFound establezca el código de respuesta adecuado.
Nigel Sampson

20
Terminé haciendo: Response.StatusCode = 404; Response. TrySkipIisCustomErrors = true; Vista de retorno ("MyCustomView"); Esto funciona perfectamente en mi situación.
Paul Hiles

@PaulHiles: Esta es la respuesta para mí en MVC3. Ojalá pudiera votarlo como una respuesta en lugar de un comentario.
Valamas

Creo que esto no funciona si se usa IIS. En mi sitio de prueba funciona bien, pero en el sitio en vivo aparece la página de error personalizado.
Andy Brown

@AndyBrown funciona tanto para IIS como para IIS Express, debe revisar su configuración de IIS (Consola de administración)
Dewfy

150

En ASP.NET MVC 3 y superior, puede devolver un HttpNotFoundResult desde el controlador.

return new HttpNotFoundResult("optional description");

44
uso:return new HttpNotFoundResult("optional description");
Valamas

66
Si regresa desde el controlador, también hay un método de conveniencia llamado HttpNotFound(). Para que puedas volver return HttpNotFound("optional description")en su lugar.
Luis Perez

1
Las cosas no eran tan convenientes en 2012 ;-)
Stefan Paul Noack

61

En MVC 4 y superior puedes usar los HttpNotFoundmétodos de ayuda incorporados :

if (notWhatIExpected)
{
    return HttpNotFound();
}

o

if (notWhatIExpected)
{
    return HttpNotFound("I did not find message goes here");
}

26

Código:

if (id == null)
{
  throw new HttpException(404, "Your error message");//RedirectTo NoFoundPage
}

Web.config

<customErrors mode="On">
  <error statusCode="404" redirect="/Home/NotFound" />
</customErrors>

Además, todos los códigos de estado disponibles existen en esta enumeración: HttpStatusCode.
user2173353

12

He usado esto:

Response.StatusCode = 404;
return null;

Gracias. Esto se ve mucho mejor que lanzar una costosa excepción en el servidor. Me pregunto si el 404 se registraría en los registros de IIS ... idealmente lo sería.
fozylet

1
Pero, en asp.net, este método no es una buena solución, ¿verdad? ya que la página web mostraría toda la información confidencial relacionada del servidor.
lzlstyle

1
Una excepción tomará menos de un milisegundo para manejar. En comparación con los pocos cientos de milisegundos solo para hacer una conexión HTTP hacia arriba y hacia atrás no tiene sentido. lanzar HttpException o devolver HttpNotFoundResult, establecer manualmente el código de estado y devolver nulo es terrible.
George


5

En NerdDinner, por ejemplo. Intenta que

public ActionResult Details(int? id) {
    if (id == null) {
        return new FileNotFoundResult { Message = "No Dinner found due to invalid dinner id" };
    }
    ...
}

Gracias, pero detrás de escena, eso arroja una HttpException similar a la sugerencia número dos en la publicación de Dewfy. Estoy buscando un poco más de control para poder mostrar una buena página de error específica de la acción, no solo redirigir a la página controlador / global 404. Parece que establecer el código de estado y volver a una vista personalizada es el camino a seguir para mi situación.
Paul Hiles

4

Ninguno de los ejemplos anteriores funcionó para mí hasta que agregué la línea media a continuación:

public ActionResult FourOhFour()
{
    Response.StatusCode = 404;
    Response.TrySkipIisCustomErrors = true; // this line made it work
    return View();
}

2
¿En serio me estás diciendo que lo simple return HttpNotFound();no funcionó para ti? ¿Cuántos años tiene su sistema?
Gone Coding

1
¿Lo intentaste return HttpNotFound();? Funciona bien con MVC 4 hacia arriba. msdn.microsoft.com/en-us/library/… "La propiedad TrySkipIisCustomErrors se usa solo cuando su aplicación está alojada en IIS 7.0. Cuando se ejecuta en modo clásico en IIS 7.0, el valor predeterminado de la propiedad TrySkipIisCustomErrors es verdadero. Cuando se ejecuta en modo integrado , el valor predeterminado de la propiedad TrySkipIisCustomErrors es falso ".
Se fue la codificación el

2

Yo suelo:

Response.Status = "404 NotFound";

Esto funciona para mí :-)




-1

Por favor, intente el siguiente código de demostración:

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.