2010-02-23 4 views

Répondre

2

L'ID est-il toujours garanti être un nombre? Si oui, vous pouvez utiliser RouteConstraints:

routes.MapRoute("ActionIDRoute", 
       "{action}/{id}", 
       new { controller = "SomeController" }, 
       new {id= new IDConstraint()}); 
routes.MapRoute("ControllerActionRoute", 
       "{controller}/{action}", 
       new {}); // not sure about this last line 

La classe IDConstraint ressemble à ceci:

public class IDConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, 
         string parameterName, RouteValueDictionary values, 
         RouteDirection routeDirection) 
    { 
     var value = values[parameterName] as string; 
     int ID; 
     return int.TryParse(value,out ID); 
    } 
} 

Fondamentalement, ce qui se passe est que vous avez deux voies identiques ici - deux paramètres, il est donc ambigous. Les contraintes d'itinéraire sont appliquées aux paramètres pour voir s'ils correspondent.

Alors:

  1. Vous appelez http://localhost/SomeController/SomeAction
  2. Il frappera le ActionIDRoute, comme cela a deux espaces réservés
  3. Comme il y a une contrainte sur le paramètre ID (uneAction), ASP.net MVC appeler la fonction match()
  4. Comme int.TryParse échoue sur uneAction, l'itinéraire est mis au rebut
  5. la route suivante qui correspond est le ControllerActionRoute
  6. Comme cela correspond et il n'y a pas de contraintes sur elle, cela sera pris

Si ID n'est pas garanti d'être un numéro, alors vous avez le problème à résoudre l'ambiguïté. La seule solution que je connaisse est le codage en dur des routes où {action}/{id} s'applique, ce qui n'est peut-être pas toujours possible.

+0

Eh bien, id est garanti pour être un nombre pour le moment, mais qui sait quand le projet se développe, si vous savez ce que je veux dire. – TPR

+0

@progtick En effet, mais cela pourrait devenir un problème. Comme dit, votre problème est que vous avez deux routes égales, c'est-à-dire: 2 routes qui ont la même apparence car elles ont le même format et le même nombre d'espaces réservés. Le nom des Placeholders n'a pas d'importance, mais vous devez d'une manière ou d'une autre les différencier. RouteConstraints est un moyen si vous savez que la sémantique est toujours différente (l'ID est toujours un nombre et Action n'est jamais un nombre, ou l'ID commence toujours par i_ et l'action ne commence jamais par i_). L'autre option: Modifiez complètement votre itinéraire pour ne pas avoir d'itinéraires similaires. –

+0

Je suis d'accord. Je vais réfléchir à cela. En attendant, votre solution d'utilisation de contraintes fonctionne pour moi. – TPR

1

Oui, vous pouvez ajouter une nouvelle règle au-dessus de la règle par défaut et fournir une valeur par défaut pour le contrôleur.

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

L'exemple transmet toutes les actions au contrôleur "Home".

+0

et quelle règle prendrait soin de la route domain.com/controller/action? J'ai AccountController qui possède une actionlog de LogOn définie. Toutefois, domain.com/account/logon n'est pas intercepté par le routetable. – TPR

+0

La règle par défaut est. – AxelEckenberger