2008-11-25 11 views
14

Je n'arrive pas à comprendre cela. J'expérimente la version bêta de MVC et j'essaie d'implémenter une route catchall de sorte que si l'utilisateur entre dans mysite.com/blah au lieu de mysite.com/home/index, il ira sur la route "Error"..Net MVC Routing Catchall ne fonctionne pas

Malheureusement, il semble que la route "Default" attrape toujours "blah" en premier. En fait, la seule route que j'ai pu obtenir avec la route "Error" est blah/blah/blah/blah.

Est-ce la façon dont il est censé fonctionner, parce que j'ai vu d'autres exemples qui ont la route "Défaut" et "Erreur" mis en place comme ça et il semble que si elles devaient taper un contrôleur qui doesn n'existe pas il frapperait la route "Erreur".

Y at-il quelque chose qui me manque (très possible) ou devrais-je simplement créer un itinéraire spécifique pour chaque contrôleur?

code J'utilise:

 routes.MapRoute(
      "Default",            // Route name 
      "{controller}/{action}/{id}",       // URL with parameters 
      new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
     ); 

     routes.MapRoute(
      "Error", 
      "{*catchall}", 
      new { controller = "Base", action = "Error", id = "404" } 
     ); 

Merci, Jeff

Répondre

2

routes MVC sont vérifiées dans l'ordre où ils sont entrés.

Mysite/blah sera trouvé par défaut. Le contrôleur sera blah, et l'action est index. Lorsque vous êtes entré dans la route mysite/blah/blah/blah/blah, vous lui avez donné une route qu'il ne pouvait pas mapper la route par défaut, puis votre route catchall a été appelée.

Pour ces autres exemples, avez-vous remarqué si des filtres d'erreur avaient été configurés? Je suis sûr que le site mvc asp.net par défaut a déjà des attributs de gestion des erreurs sur les pages.

+0

Merci, c'est la compréhension que je suis venu, mais je ne voulais pas accepter en fonction de ce que j'ai vu, et ce que je m'attendais. Mais je vais apprendre à m'en occuper. –

5

Afin de gérer les erreurs que j'utilisé l'événement Application_Error dans l'un de mes projets:

protected void Application_Error(object sender, EventArgs e) 
{ 
    Exception exception = Server.GetLastError(); 
    HttpException httpException = exception as HttpException; 
    if (httpException != null) 
    { 
     RouteData routeData = new RouteData(); 
     routeData.Values.Add("controller", "Error"); 
     routeData.Values.Add("action", "HttpError500"); 

      if (httpException.GetHttpCode() == 404) 
      { 
       routeData.Values["action"] = "HttpError404"; 
      } 

     Server.ClearError(); 
     Response.Clear(); 
     IController errorController = new ErrorController(); 
     errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); 
    } 
} 
+0

Ce n'est pas le bon endroit pour gérer les exceptions, et vous changez aussi la signification d'une exception en la désactivant.Cela pourrait potentiellement rendre le débogage très, très difficile. –

+1

Je ne vois pas pourquoi l'utilisation du gestionnaire Application_Error rendrait le débogage difficile. Si vous consignez l'exception, vous aurez la trace complète de la pile. Un autre problème avec la route * catchall est qu'elle ne sera pas appelée si une exception survient dans une action du contrôleur, donc si vous voulez gérer 500 erreurs, vous devrez le faire ailleurs. Je préfère avoir tout le code de gestion des exceptions à un endroit. –

+0

Le plus gros problème est que vous perdez beaucoup de votre contexte au moment où l'erreur arrive à Application_Error, comme l'objet session, et si vous ne tenez pas compte de ces éléments, le débogage devient un cauchemar. –

6

Votre première route va attraper le plus urls puisque vous avez par défaut pour les éléments, vous pouvez visualiser cela en utilisant la route débogueur de Phil Haack, voir le lien:

Route Debugger

+0

Cela semble utile aussi. Merci! –

0

Cela peut aussi utile pour gérer des problèmes de MVC catchall:

routes.MapRoute(
    "Default",            // Route name 
    "{controller}/{action}/{*id}",       // URL with parameters 
    new { controller = "Home", action = "Index", id = "" } // Parameter defaults 
); 

Autrement dit, où il est dit {id}, changez-le en {*id}. Cela permet au paramètre id final consommer autant chemin qui pourrait encore être passé dans la règle par défaut accepte ceci:.

/personne/nom/Joe

Mais pas:

/produits/liste/sortby/name

La deuxième URL lancera un 404 sans cette modification de l'itinéraire.

+0

J'ai essayé ceci et ai été partout sur l'Internet essayant de le comprendre mais cela ne fonctionne pas pour moi. Si je passe 2 segments dans l'URL, j'obtiens l'erreur 404 si j'ajoute l'astérisque ou non. Aucun conseil? – DavidHyogo

+0

Cela peut être mieux comme une nouvelle question - quelles sont les valeurs par défaut que vous définissez (troisième ligne dans cet exemple)? Un échantillon de code complet serait préférable, ce qui nécessite une question distincte. –

+0

Bonne idée Chris, mais j'ai trouvé mon erreur stupide. Je définissais mes itinéraires au mauvais endroit pour MVC 4, et ils étaient ignorés. Voir ma réponse à http://stackoverflow.com/questions/7515644/infinite-url-parameters-for-asp-net-mvc-route/14835667#14835667 Je suis maintenant heureux de créer toutes sortes de définitions de route de fantaisie! – DavidHyogo