2010-04-07 3 views
2

La route suivante Page/View/Id irait à la méthode View dans le contrôleur de page. Je voudrais également la route suivante:Comment séparer des routes qui ont le même chemin mais font des choses différentes?

/{page-title} 

pour aller à la même méthode. C'est pour que je puisse avoir des URL comme les suivantes:

http://www.mysite.com/This-Is-a-Page 

Comment puis-je configurer cela, peut-être This-Is-a-Page envisage un contrôleur aussi?

+0

Cela a été posté deux fois et est le même que: http://stackoverflow.com/questions/2591524/asp-net-mvc-routes –

+0

J'ai supprimé le double post – IceHeat

Répondre

0

Vous pourriez être en mesure d'ajouter un fourre-tout, comme si (lieu cette après les routes par défaut):

routes.MapRoute(
    null, 
    "{*query}", 
    new { controller = "SomeController", action = "SomeAction" } 
); 

Et la signature d'action se présente comme suit:

public ActionResult(string query) 
+0

Cela ne fonctionne que si vous définissez avant la valeur par défaut, si elle est définie après la valeur par défaut, elle suppose que le titre est un contrôleur. – IceHeat

+1

Pas s'il n'y a pas de contrôleur pour ce titre. Cette route attrape tout ce qui ne correspond à aucun de ce qui précède. – Mickel

4

Si les deux vos routes "contrôleur" et "page" itinéraires (voir ci-dessous) utilisent le même /something, alors vous devrez mettre en œuvre les règles suivantes:

En haut de vos itinéraires:

route. MapRoute(
    "ControllerRoute" 
    "{controller}", 
    new { controller = "Home", action = "Index" } 
    new { controller = GetControllerNameRegex() } 
); 

route.MapRoute(
    "PageRoute", 
    "{pageSlug}" 
    new { controller = "Page", action = "ShowPage" } 
); 
  • Aucune page peut avoir un nom qui correspond à un contrôleur en cours d'utilisation.
  • Ou aucun contrôleur ne peut avoir le nom correspondant à une page en cours d'utilisation.

Puisque vous ne pouvez pas vraiment faire ce dernier programme, mais you can do the former programmatically, vous pouvez ajouter une contrainte personnalisée à vos itinéraires de contrôleur, de sorte qu'il ne touche que si vous arrive de taper le nom d'un contrôleur:

private static string GetControllerNameRegex() 
{ 
    var controllerNamesRegex = new StringBuilder(); 
    List<string> controllers = GetControllerNames(); 
    controllers.ForEach(s => 
      controllerNamesRegex.AppendFormat("{0}|", s)); 
    return controllerNamesRegex.ToString().TrimEnd('|'); 
} 

private static List<Type> GetSubClasses<T>() 
{ 
    return Assembly.GetCallingAssembly().GetTypes().Where(type => 
      type.IsSubclassOf(typeof(T))).ToList(); 
} 

public List<string> GetControllerNames() 
{ 
    List<string> controllerNames = new List<string>(); 
    GetSubClasses<Controller>().ForEach(type => controllerNames.Add(type.Name)); 
    return controllerNames; 
} 

NB: mieux serait de vous assurer de ne pas avoir des pages portant le nom de votre contrôleur, et vous pouvez utiliser le code ci-dessus pour appliquer ce lors de l'exécution.

Questions connexes