122 votes

Acheminement pour une page d'erreur 404 personnalisée dans ASP.NET MVC

Je suis en train de créer une page d'erreur HTTP 404 personnalisée lorsque quelqu'un tape une URL qui n'invoque pas une action ou un contrôleur valide dans ASP.NET MVC, au lieu d'afficher l'erreur générique "Ressource non trouvée" d'ASP.NET.

Je ne veux pas utiliser le fichier web.config pour gérer cela.

Y a-t-il un genre de magie de routage que je peux faire pour attraper toutes les URLs invalides?

Mise à jour: J'ai essayé la réponse donnée, cependant j'obtiens toujours le message laid "Ressource non trouvée".

Autre mise à jour: Ok, apparemment quelque chose a changé dans RC1. J'ai même essayé de capturer spécifiquement le 404 sur une HttpException et ça me donne toujours la page "Ressource non trouvée".

J'ai même utilisé la fonctionnalité de ressources de MvcContrib et rien - même problème. Des idées?

0 votes

0 votes

@Peter C'est la solution que j'ai ajoutée en plus de remplacer la fonction HandleUnknownAction pour afficher une vue de page non trouvée lorsqu'une action n'existe pas, puis en utilisant le gestionnaire d'erreurs personnalisé ASP.net intégré pour gérer tout autre élément loufoque que les utilisateurs pourraient saisir.

0 votes

@pete Cela fonctionne aussi bien stackoverflow.com/questions/619895/…

111voto

Andrew Orsich Points 24503

J'ai essayé d'activer les erreurs personnalisées sur le serveur de production pendant 3 heures, il semble que j'aie trouvé la solution finale pour le faire en ASP.NET MVC sans avoir à utiliser de routes.

Pour activer les erreurs personnalisées dans une application ASP.NET MVC, nous avons besoin de (IIS 7+):

  1. Configurer les pages personnalisées dans le fichier web config sous la section system.web:

    RemoteOnly signifie que sur le réseau local, vous verrez les vraies erreurs (très utile pendant le développement). Nous pouvons également réécrire la page d'erreur pour n'importe quel code d'erreur.

  2. Définir le paramètre magique de réponse et le code d'état de réponse (dans le module de gestion des erreurs ou dans l'attribut de gestion des erreurs)

      HttpContext.Current.Response.StatusCode = 500;
      HttpContext.Current.Response.TrySkipIisCustomErrors = true;
  3. Définir un autre paramètre magique dans le fichier web config sous la section system.webServer:

C'était la dernière chose que j'ai trouvée et après cela, je peux voir les erreurs personnalisées sur le serveur de production.

8 votes

Ce n'est toujours pas une solution idéale. Cela ne vous donne pas de codes de réponse HTTP appropriés. L'utilisation de customErrors entraîne une redirection 302 uniquement pour charger votre page d'erreur.

0 votes

@Ek0nomik Je n'ai jamais vu de solutions idéales :)

2 votes

@JustinHelgerson J'ai mis en place un ErrorController pour chaque code statut et j'ai défini les codes de réponse à l'intérieur de ces actions et cela définit les codes de réponse correctement.. J'ai testé avec Fiddler et les codes de statut 404 répondent avec un 404 et les pages avec des erreurs 500 répondent avec un 500. Et dans les deux cas, mes vues d'erreurs personnalisées sont servis.

42voto

Jack Smit Points 869

J'ai réussi à faire fonctionner la gestion des erreurs en créant un ErrorController qui renvoie les vues dans cet article. J'ai également dû ajouter le "Catch All" à la route dans global.asax.

Je ne vois pas comment il pourra accéder à l'une de ces pages d'erreur s'il n'est pas dans le Web.config ..? Mon Web.config devait spécifier:

customErrors mode="On" defaultRedirect="~/Error/Unknown"

et j'ai aussi ajouté:

error statusCode="404" redirect="~/Error/NotFound"

2 votes

Merci - cela m'a aidé, 2 ans plus tard! Que faites-vous si vous ne voulez qu'une erreur personnalisée pour 404, rien d'autre?

1 votes

@Shaul une autre année plus tard... ne définissez pas la defaultRedirect, excluez complètement l'attribut.

30voto

Yasser Points 9307

Source

NotFoundMVC - Fournit une page 404 conviviale chaque fois qu'un contrôleur, une action ou une route n'est pas trouvé dans votre application ASP.NET MVC3. Une vue appelée NotFound est rendue à la place de la page d'erreur ASP.NET par défaut.

Vous pouvez ajouter ce plugin via nuget en utilisant : Install-Package NotFoundMvc

NotFoundMvc s'installe automatiquement au démarrage de l'application web. Il gère toutes les différentes manières dont une HttpException 404 est généralement lancée par ASP.NET MVC. Cela inclut un contrôleur, une action et une route manquants.

Guide d'installation étape par étape :

1 - Cliquez avec le bouton droit sur votre projet et sélectionnez Gérer les packages Nuget...

2 - Recherchez NotFoundMvc et installez-le. entrer la description de l'image ici

3 - Une fois l'installation terminée, deux fichiers seront ajoutés à votre projet. Comme le montrent les captures d'écran ci-dessous.

entrer la description de l'image ici

4 - Ouvrez le NotFound.cshtml nouvellement ajouté présent dans Views/Shared et modifiez-le à votre guise. Maintenant, lancez l'application et saisissez une URL incorrecte, vous serez accueilli par une page 404 conviviale.

entrer la description de l'image ici

Les utilisateurs ne recevront plus d'erreurs comme Erreur de serveur dans l'application '/' Ressource introuvable.

J'espère que cela aidera :)

P.S : Félicitations à Andrew Davey pour avoir créé un tel plugin génial.

0 votes

@niico En regardant le code source, il semble définir le code de réponse à 404, donc oui.

23voto

Amila Points 798

Essayez ceci dans le fichier web.config pour remplacer les pages d'erreur IIS. C'est la meilleure solution selon moi, et cela envoie également le bon code d'état.

Plus d'informations sur Tipila - Utiliser des pages d'erreur personnalisées ASP.NET MVC

1 votes

+1. C'est la seule chose qui semblait fonctionner de manière constante pour moi sur MVC5 avec plusieurs zones.

0 votes

Il s'agit de la solution la plus simple. Vous ne pouvez pas utiliser la syntaxe razor sur votre page d'erreur cependant.

16voto

Sujeewa Points 151

Cette solution ne nécessite pas de modifications de fichiers web.config ou de routes catch-all.

Tout d'abord, créez un contrôleur comme ceci;

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Erreur régulière";
        return View();
    }

    public ActionResult NotFound404()
    {
        ViewBag.Title = "Erreur 404 - Fichier non trouvé";
        return View("Index");
    }
}

Ensuite, créez la vue sous "Views/Error/Index.cshtml" comme suit;

 @{
      Layout = "~/Views/Shared/_Layout.cshtml";
  }                     
  Nous sommes désolés, la page que vous recherchez n'est malheureusement pas ici.

Ensuite, ajoutez ce qui suit dans le fichier Global.asax comme ci-dessous:

protected void Application_Error(object sender, EventArgs e)
{
        // Faites ce que vous voulez avec l'erreur

        // Affichez la page d'erreur personnalisée...
        Server.ClearError(); 
        var routeData = new RouteData();
        routeData.Values["controller"] = "Error";

        if ((Context.Server.GetLastError() is HttpException) && ((Context.Server.GetLastError() as HttpException).GetHttpCode() != 404))
        {
            routeData.Values["action"] = "Index";
        }
        else
        {
            // Gérer l'erreur 404 et le code de réponse
            Response.StatusCode = 404;
            routeData.Values["action"] = "NotFound404";
        } 
        Response.TrySkipIisCustomErrors = true; // Si vous utilisez IIS7, ajoutez cette ligne
        IController errorsController = new ErrorController();
        HttpContextWrapper wrapper = new HttpContextWrapper(Context);
        var rc = new System.Web.Routing.RequestContext(wrapper, routeData);
        errorsController.Execute(rc);

        Response.End();
}

Si vous obtenez toujours la page d'erreur IIS personnalisée après avoir fait cela, assurez-vous que les sections suivantes sont commentées (ou vides) dans le fichier de configuration web:

0 votes

Je ne pense pas que cette approche fonctionnera dans tous les cas, car une erreur 404 est souvent interceptée par le serveur web et n'est donc jamais gérée au niveau de l'application.

0 votes

Je voudrais ajouter que si vous suivez cette approche, je recommanderais d'ajouter un Response.End(); à la fin de votre gestionnaire Application_Error. Sans cela, seule la première occurrence d'une erreur est déclenchée pour une session donnée, ce qui pose problème lorsque vous avez, par exemple, un journal des erreurs personnalisé dans le gestionnaire Application_Error.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X