2009-06-20 11 views
4

Je joue avec ASP.Net MVC depuis un moment. J'ai trouvé que la chose la plus difficile à faire est la table de routage.Stratégie de routage ASP.Net MVC

J'ai trouvé que la plupart des exemples laissaient la route par défaut en place. J'ai trouvé que cela conduit à beaucoup d'erreurs où la route par défaut redirige vers HomeController avec une action qui n'existe pas. Je suis par la suite arrivé à une configuration de routage où je définis explicitement toutes les combinaisons contrôleur/action que je veux autoriser avec un fourre-tout à la fin pour rediriger vers un message d'erreur étrange. une page 404 qui montre un message d'erreur sensible.

Ai-je raté quelque chose ici? Ou est-ce vraiment un bon moyen de faire les choses? En regardant les réponses, je pense que je ferais mieux de clarifier la question un peu. J'essaie d'infaillible le schéma de routage du site Web que je construis. J'ai remarqué que quand je pars dans la route par défaut {controller}/{action}/{id} toutes sortes d'URL où je voudrais afficher une erreur 404 effectivement être acheminé au HomeController avec une action invalide et entraîner une erreur laide message à la place.

Je suis un peu confus parce que la plupart des exemples de code restent dans la route par défaut. Y at-il une raison pour laquelle il est là ou est-ce correct de l'enlever?

Le schéma J'utilise semble maintenant un peu comme ce

 routes.MapRoute("About", "About", new {controller = "Page", action = "About"}); 
     routes.MapRoute("SignIn", "SignIn", new {controller = "Page", action = "SignIn"}); 
     routes.MapRoute("SignOut", "SignOut", new {controller = "Page", action = "SignOut"}); 
     routes.MapRoute("Authenticate", "Authenticate", new { controller = "Authentication", action = "Authenticate" }); 

     routes.MapRoute("CatchAll", "{*url}", new { controller = "Error", action = "Http404" }); 

J'ai une route spécifiée pour chaque action dans le système. Et un catchall pour afficher un 404 à la fin. Est-ce un bon moyen de le faire ou existe-t-il un moyen plus simple de rendre le système de routage infaillible?

+0

Je suis dans le même bateau. Je pensais que le crochet tout fonctionnerait si la route par défaut ne pouvait pas trouver un contrôleur + action. Au lieu de cela, la fabrique de contrôleurs émet une exception. Êtes-vous toujours en route explicite? – dotjoe

Répondre

7

Si cela est la route par défaut que vous utilisez:

routes.MapRoute(
      "Default",            
      "{controller}/{action}/{id}",       
      new { controller = "Home", action = "Index", id = "" } 
     ); 

puis « HomeController » et l'action « Index » seront utilisés par défaut, sauf si votre URL indique le contraire.

Par exemple:

"http://www.something.com/" utilisera l'action Index du contrôleur Home, car ce sont le contrôleur par défaut et de l'action.

"http://www.something.com/foo" utilisera l'action Index du contrôleur Foo, car "Index" est l'action par défaut.

"http://www.something.com/foo/bar" utilisera l'action "bar" du contrôleur Foo

"http://www.something.com/foo/bar/1" utilisera l'action "barre" du contrôleur Foo, en passant "1" comme paramètre "id"

Si vous ne N'ayez pas de "FooController", tout ce qui commence par "http://www.something.com/foo" échouera. De même, si votre FooController n'a pas d'action "Barre", alors "http://www.something.com/foo/bar" échouera.

Vous savez peut-être déjà tout ce que j'ai posté ci-dessus. Si c'est le cas, afficherez-vous les URL qui échouent, afin que nous puissions mieux vous aider?

+0

Vous n'avez pas vraiment répondu à ma question (je suppose que c'est de ma faute si vous posez des questions vagues) mais vous avez clarifié d'autres choses que je ne connaissais pas, merci :-) J'ai essayé d'éclaircir un peu la question. – Mendelt

2

Je préfère définir des routes explicitement pour chaque méthode d'action.

Découvrez this.

+0

Merci pour le pointeur, va vérifier cela! – Mendelt

0

Cette question est un peu plus ancienne, mais je viens juste de la rencontrer, ayant la même question. Je n'ai pas trop envie de définir une tonne de routes manuellement, ni d'ajouter un tas d'attributs pour que les routes soient créées automatiquement pour moi (le lien d'Arnis). Après quelques considérations, j'ai décidé d'utiliser un simple RouteConstraint que j'ai créé. J'ai modifié la route par défaut à utiliser et ajouté mon 404 catchall ci-dessous la valeur par défaut, comme ceci:

 
routes.MapRoute(
    "Default", 
    "{controller}/{action}/{id}", 
    new { controller = "Home", action = "Index", id = "" }, 
    new { controller = new ExistingControllerActionConstraint() } 
); 

routes.MapRoute(
    "CatchAll", 
    "{*catchall}", 
    new { controller = "Home", action = "NotFound" } 
); 

Et la classe contrainte:

 
public class ExistingControllerActionConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     Type t = Type.GetType("MvcApplication_BareMinimum7.Controllers." + values["controller"] + "Controller"); 

     if (t == null) 
     { 
      return false; 
     } 

     MethodInfo mi = (from m in t.GetMethods() where m.Name == values["action"].ToString() select m).FirstOrDefault(); 

     return (mi != null); 
    } 
} 

Le coût de la réflexion et LINQ utilisé peut l'emporter sur les coût d'enregistrement des dizaines de centaines de routes, mais cela me semble plus propre.