Comment obtenir l'action MVC pour renvoyer 404


142

J'ai une action qui prend dans une chaîne qui est utilisée pour récupérer des données. Si cette chaîne ne renvoie aucune donnée (peut-être parce qu'elle a été supprimée), je souhaite renvoyer un 404 et afficher une page d'erreur.

Actuellement, j'utilise simplement une vue spéciale qui affiche un message d'erreur convivial spécifique à cette action indiquant que l'élément n'a pas été trouvé. Cela fonctionne bien, mais dans l'idéal, vous souhaitez renvoyer un code d'état 404 afin que les moteurs de recherche sachent que ce contenu n'existe plus et puissent le supprimer des résultats de recherche.

Quelle est la meilleure manière de s'occuper de ça?

Est-ce aussi simple que de définir Response.StatusCode = 404?


vous devez également conserver Response.TrySkipIisCustomErrors = true; La réponse de @ganders était une bouée de sauvetage ...
Thunder

Réponses:


111

Il y a plusieurs façons de le faire,

  1. Vous avez raison dans le code aspx commun, il peut être attribué de la manière spécifiée
  2. throw new HttpException(404, "Some description");

1
Une chose à surveiller est que si vous avez une page customError configurée pour gérer 404, cette page d'erreur renverra 200 (la page introuvable a été trouvée ... :-(). J'ai tendance à lancer l'exception de dire BlogController et demandez à l'action NotFound de définir le code de réponse approprié.
Nigel Sampson

20
J'ai fini par faire: Response.StatusCode = 404; Response.TrySkipIisCustomErrors = true; return View ("MyCustomView"); Cela fonctionne parfaitement dans ma situation.
Paul Hiles

@PaulHiles: C'est la réponse pour moi dans MVC3. J'aimerais pouvoir le voter comme une réponse plutôt qu'un commentaire.
Valamas

Cela ne fonctionne pas, je pense, si vous utilisez IIS. Sur mon site de test, cela fonctionne bien, mais sur le site en direct, la page d'erreur personnalisée entre en jeu.
Andy Brown

@AndyBrown cela fonctionne pour IIS ainsi que pour IIS Express, vous devez revoir votre configuration d'IIS (console d'administration)
Dewfy

150

Dans ASP.NET MVC 3 et versions ultérieures, vous pouvez renvoyer un HttpNotFoundResult à partir du contrôleur.

return new HttpNotFoundResult("optional description");

4
utilisation:return new HttpNotFoundResult("optional description");
Valamas

6
Si vous revenez depuis le contrôleur, il existe également une méthode pratique appelée HttpNotFound(). Vous pouvez donc revenir à la return HttpNotFound("optional description")place.
Luis Perez

1
Les choses n'étaient pas si pratiques en 2012 ;-)
Stefan Paul Noack

61

Dans MVC 4 et supérieur, vous pouvez utiliser les HttpNotFoundméthodes d'aide intégrées :

if (notWhatIExpected)
{
    return HttpNotFound();
}

ou

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

26

Code:

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

Web.config

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

En outre, tous les codes d'état disponibles existent dans cette énumération: HttpStatusCode.
user2173353

12

J'ai utilisé ceci:

Response.StatusCode = 404;
return null;

Je vous remercie. Cela semble bien mieux que de lancer une exception coûteuse sur le serveur. Je me demande si le 404 serait enregistré dans les journaux IIS ... idéalement, ce serait le cas.
fozylet le

1
Mais, sur asp.net, cette méthode n'est pas une bonne solution, non? puisque la page Web afficherait toutes les informations sensibles associées du serveur.
lzlstyle

1
Une exception prendra moins d'une milliseconde à traiter. Comparé aux quelques centaines de millièmes de secondes juste pour faire une connexion HTTP aller-retour, cela n'a aucun sens. lancer HttpException ou retourner HttpNotFoundResult, définir manuellement le code d'état et renvoyer null est terrible.
George


5

Dans NerdDinner par exemple. Essayez- le

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

Merci, mais dans les coulisses, cela lance une HttpException similaire à la suggestion numéro deux dans le message de Dewfy. Je recherche un peu plus de contrôle afin de pouvoir afficher une belle page d'erreur spécifique à l'action, pas seulement la redirection vers la page contrôleur / global 404. Il semble que la définition du code d'état et le retour à une vue personnalisée soient la voie à suivre pour ma situation.
Paul Hiles

4

Aucun des exemples ci-dessus n'a fonctionné pour moi jusqu'à ce que j'aie ajouté la ligne médiane ci-dessous:

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

2
Êtes-vous en train de me dire sérieusement que le simple return HttpNotFound();n'a pas fonctionné pour vous? Quel âge a votre système?
Fini le codage

1
Avez-vous essayé return HttpNotFound();? Cela fonctionne très bien avec MVC 4 à la hausse. msdn.microsoft.com/en-us/library/… "La propriété TrySkipIisCustomErrors est utilisée uniquement lorsque votre application est hébergée dans IIS 7.0. Lors de l'exécution en mode classique dans IIS 7.0, la valeur par défaut de la propriété TrySkipIisCustomErrors est true. Lors de l'exécution en mode intégré , la valeur par défaut de la propriété TrySkipIisCustomErrors est false. "
Fini le codage

2

J'utilise:

Response.Status = "404 NotFound";

Cela fonctionne pour moi :-)



0

Vous pouvez également faire:

        if (response.Data.IsPresent == false)
        {
            return StatusCode(HttpStatusCode.NoContent);
        }

-1

Veuillez essayer le code de démonstration suivant:

public ActionResult Test()

{
  return new HttpStatusCodeResult (404,"Not found");
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.