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?

Paul Hiles
fuente
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");
Rocío
fuente
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");
Stefan Paul Noack
fuente
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");
}
Codificación ido
fuente
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>
Sinan BARAN
fuente
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;
Wout
fuente
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
10

Si está trabajando con .NET Core, puede return NotFound()

Robert Paulsen
fuente
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" };
    }
    ...
}
cem
fuente
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();
}
gaders
fuente
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í :-)

bruno
fuente
2

En .NET Core 1.1:

return new NotFoundObjectResult(null);
alimenta a los perros
fuente
1
Si no está devolviendo un objeto, devolver NotFound () es más apropiado, pero en cualquier caso, no obtendrá una página de error amigable a menos que lo maneje con algo como StatusCodePagesWithReExecute. Ver devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core
Paul Hiles
0

También puedes hacer:

        if (response.Data.IsPresent == false)
        {
            return StatusCode(HttpStatusCode.NoContent);
        }
Christof Mehlstäubler
fuente
-1

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

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}
user4326800
fuente