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?

Paul Hiles
la source
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");
Dewfy
la source
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");
Stefan Paul Noack
la source
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");
}
Codage terminé
la source
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>
Sinan BARAN
la source
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;
Wout
la source
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
10

Si vous travaillez avec .NET Core, vous pouvez return NotFound()

Robert Paulsen
la source
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" };
    }
    ...
}
cem
la source
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();
}
ganders
la source
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 :-)

Bruno
la source
2

Dans .NET Core 1.1:

return new NotFoundObjectResult(null);
aliments pour animaux
la source
1
Si vous ne renvoyez pas un objet, renvoyer NotFound () est plus approprié mais dans les deux cas, vous n'obtiendrez pas de page d'erreur conviviale à moins que vous ne le gériez avec quelque chose comme StatusCodePagesWithReExecute. Voir devtrends.co.uk/blog/handling-404-not-found-in-asp.net-core
Paul Hiles
0

Vous pouvez également faire:

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

Veuillez essayer le code de démonstration suivant:

public ActionResult Test()

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