web-dev-qa-db-fra.com

Routage pour la page d'erreur ASP.NET MVC 404 personnalisée

J'essaie de créer une page d'erreur HTTP 404 personnalisée lorsque quelqu'un tape dans une URL Qui n'appelle pas une action ou un contrôleur valide dans ASP.NET MVC, au lieu d'afficher le générique "Ressource introuvable" ASP.NET Erreur.

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

Existe-t-il une magie du routage que je peux faire pour récupérer les URL non valides?

Mise à jour: J'ai essayé la réponse donnée, mais le message "Ressource non trouvée" moche toujours.

Une autre mise à jour: Ok, apparemment, quelque chose a changé dans RC1. J'ai même essayé de piéger spécifiquement 404 sur une HttpException et cela ne donne toujours que la page "Ressource introuvable".

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

110
dswatik

Ajoutez simplement catch all route à la fin du tableau des routes et affichez la page de votre choix.

Voir: Comment puis-je créer un catch all route pour traiter les requêtes '404 pages non trouvées' pour ASP.NET MVC?

9
Alex Reitbort

J'ai essayé d'activer les erreurs personnalisées sur le serveur de production pendant 3 heures. Il semble que j'ai trouvé la solution finale. Comment le faire dans ASP.NET MVC sans routes.

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

  1. Configurez les pages personnalisées dans la configuration Web dans la section system.web:

    <customErrors mode="RemoteOnly"  defaultRedirect="~/error">
        <error statusCode="404" redirect="~/error/Error404" />
        <error statusCode="500" redirect="~/error" />
    </customErrors>
    

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

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

      HttpContext.Current.Response.StatusCode = 500;
      HttpContext.Current.Response.TrySkipIisCustomErrors = true;
    
  3. Définissez un autre paramètre magique dans la configuration Web dans la section system.webServer:

    <httpErrors errorMode="Detailed" />
    

C'est 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.

101
Andrew Orsich

Mon traitement des erreurs a fonctionné en créant un ErrorController qui renvoie les vues de cet article. J'ai également dû ajouter le "Catch All" à la route dans global.asax. 

Je ne vois pas comment cela aboutirait à l'une de ces pages d'erreur si ce n'est dans le fichier Web.config ..? Mon Web.config devait spécifier:

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

et puis j'ai aussi ajouté:

error statusCode="404" redirect="~/Error/NotFound"
41
Jack Smit

La source

NotFoundMVC - Fournit une page 404 conviviale lorsqu'un contrôleur, une action ou une route est introuvable 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 lors du démarrage de l’application Web. Il gère les différentes manières dont une exception 404 HttpException est généralement levée par ASP.NET MVC. Cela inclut un contrôleur manquant, une action et un itinéraire.

Guide d'installation étape par étape:

1 - Faites un clic droit sur votre projet et sélectionnez Gérer les paquets de nugets ...

2 - Recherchez NotFoundMvc et installez-le .enter image description here

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

enter image description here

4 - Ouvrez le fichier NotFound.cshtml récemment ajouté dans Views/Shared et modifiez-le à votre guise. Maintenant, exécutez l'application et tapez une URL incorrecte, et vous serez accueilli avec une page 404 conviviale.

enter image description here

Pas plus, les utilisateurs recevront-ils un message d'erreur comme Server Error in '/' Application. The resource cannot be found.

J'espère que cela t'aides :)

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

27
Yasser

Essayez ceci dans web.config pour remplacer IIS les pages d'erreur. C’est la meilleure solution, je suppose, et le code d’état correct est également envoyé.

<system.webServer>
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="404" path="Error404.html" responseMode="File" />
    <error statusCode="500" path="Error.html" responseMode="File" />
  </httpErrors>
</system.webServer>

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

19
Amila

Cette solution n'a pas besoin de modifications de fichier web.config ni d'itinéraires attrayants. 

Tout d’abord, créez un contrôleur comme celui-ci;

public class ErrorController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Title = "Regular Error";
        return View();
    }

    public ActionResult NotFound404()
    {
        ViewBag.Title = "Error 404 - File not Found";
        return View("Index");
    }
}

Puis créez la vue sous "Views/Error/Index.cshtml" en tant que;

 @{
      Layout = "~/Views/Shared/_Layout.cshtml";
  }                     
  <p>We're sorry, page you're looking for is, sadly, not here.</p>

Puis ajoutez ce qui suit dans le fichier asax global comme ci-dessous: 

protected void Application_Error(object sender, EventArgs e)
{
        // Do whatever you want to do with the error

        //Show the custom error page...
        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
        {
            // Handle 404 error and response code
            Response.StatusCode = 404;
            routeData.Values["action"] = "NotFound404";
        } 
        Response.TrySkipIisCustomErrors = true; // If you are using IIS7, have this line
        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 personnalisée IIS après cela, assurez-vous que les sections suivantes sont commentées (ou vides) dans le fichier de configuration Web: 

<system.web>
   <customErrors mode="Off" />
</system.web>
<system.webServer>   
   <httpErrors>     
   </httpErrors>
</system.webServer>
15
Sujeewa

Si vous travaillez dans MVC 4, vous pouvez regarder ceci solution, cela a fonctionné pour moi.

Ajoutez la méthode Application_Error suivante à mon Global.asax:

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    RouteData routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Index");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    IController controller = new ErrorController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();

Le contrôleur lui-même est vraiment simple:

public class ErrorController : Controller
{
    public ActionResult Index(int statusCode, Exception exception)
    {
        Response.StatusCode = statusCode;
        return View();
    }
}

Vérifiez le code source complet de Mvc4CustomErrorPage sur GitHub .

5
Duc Hoang

Voici la vraie réponse qui permet de personnaliser entièrement la page d'erreur en un seul endroit . Pas besoin de modifier web.config ou de créer du code séparé.

Fonctionne également dans MVC 5.

Ajoutez ce code au contrôleur:

        if (bad) {
            Response.Clear();
            Response.TrySkipIisCustomErrors = true;
            Response.Write(product + I(" Toodet pole"));
            Response.StatusCode = (int)HttpStatusCode.NotFound;
            //Response.ContentType = "text/html; charset=utf-8";
            Response.End();
            return null;
        }

Basé sur http://www.eidias.com/blog/2014/7/2/mvc-custom-error-pages

0
Andrus

Je vais parler de certains cas spécifiques,

si vous utilisez la méthode "PageNotFound" dans HomeController comme ci-dessous

[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

ça ne marcherait pas ça. Mais vous devez effacer les balises Route comme ci-dessous,

//[Route("~/404")]
public ActionResult PageNotFound()
{
  return MyView();
}

Et si vous le changez en tant que méthode Name dans web.config cela fonctionne. N'oubliez cependant pas de faire le code comme ci-dessous dans web.config

<customErrors mode="On">
  <error statusCode="404" redirect="~/PageNotFound" /> 
 *// it is not "~/404" because it is not accepted url in Route Tag like [Route("404")]*
</customErrors>
0
Furkan öztürk

J'ai eu le même problème. Au lieu d'ajouter l'attribut customErrors dans le fichier web.config de votre dossier Views, vous devez l'ajouter au fichier web.config du dossier racine de vos projets.

0
SmokeIT