2010-07-23 7 views
3

Actuellement, je les URL qui ressemblent à ceci:ASP.NET MVC 2 Routage avec des paramètres cohérents supplémentaires (pas seulement du contrôleur et d'action)

http://www.example.com/user/create 
http://www.example.com/user/edit/1 

Mais maintenant, je dois soutenir plusieurs organisations et leurs utilisateurs. Je dois avoir quelque chose comme ceci:

http://www.example.com/org-name/user/create 
http://www.example.com/org-name/user/edit/1 

j'avais du mal à obtenir les routes pour fonctionner parfaitement, donc je devais ajouter un jeton au début du nom de l'organisation afin que le routage ne pas confondre avec une paire contrôleur/action. Pas une affaire énorme mais mes URL ressemblent à ceci maintenant:

http://www.example.com/o/org-name/user/create 
http://www.example.com/o/org-name/user/edit/1 

C'est très bien. Je peux vivre avec ça.

est ici où je suis en ennuis:
Quand je générer des URL une fois que j'ai une organisation choisie, il ne persiste le nom de l'organisation. Alors, quand je suis ici:

http://www.example.com/o/org-name 

... et j'utilise Url.Action ("User", "Créer") pour générer une URL, il affiche:

/user/create 

... plutôt que ce que je veux:

/o/org-name/user/create 

Voici ce que mes routes ressemblent à (dans l'ordre):

 routes.MapRouteLowercase(
      "DefaultOrganization", 
      "{token}/{organization}/{controller}/{action}/{id}", 
      new { id = UrlParameter.Optional }, 
      new { token = "o" } 
     ); 

     routes.MapRouteLowercase(
      "OrganizationDashboard", 
      "{token}/{organization}/{controller}", 
      new { controller = "Organization", action = "Dashboard" }, 
      new { token = "o" } 
     ); 

     routes.MapRouteLowercase(
      "DefaultSansOrganization", 
      "{controller}/{action}/{id}", 
      new { controller = "Core", action="Dashboard", id = UrlParameter.Optional } 
     ); 

Il est similaire à cette question ASP.NET MVC Custom Routing Long Custom Route not Clicking in my Head. J'ai le sentiment que cela va finir par être évident, mais c'est vendredi et ça n'arrive pas en ce moment.


EDIT:
a suggéré de Womp travaillé, mais ce serait la meilleure façon d'automatiser ce?

public static string ActionPrepend(this UrlHelper helper, string actionName, string controllerName) 
    { 
     string currentUrl = helper.RequestContext.RouteData.Values["url"] as string; 
     string actionUrl = string.Empty; 

     if (currentUrl != null) 
     { 
      Uri url = new Uri(currentUrl); 

      if (url.Segments.Length > 2 && url.Segments[1] == "o/") 
       actionUrl = string.Format("{0}{1}{2}{3}", url.Segments[0], url.Segments[1], url.Segments[2], 
        helper.Action(actionName, controllerName)); 
     } 

     if(string.IsNullOrEmpty(actionUrl)) 
      actionUrl = helper.Action(actionName, controllerName); 

     return actionUrl; 
    } 


EDIT:
fixe mes itinéraires pour travailler plutôt que le piratage ensemble. La solution finale n'a pas besoin du stupide {token} dans l'URL. Peut-être cela va aider quelqu'un d'autre:

routes.MapRouteLowercase(
    "Organization", 
    "{organization}/{controller}/{action}/{id}", 
    new { controller = "Organization", action = "Dashboard", id = UrlParameter.Optional }, 
    new { organization = @"^(?!User|Account|Report).*$" } 
); 

routes.MapRouteLowercase(
    "Default", 
    "{controller}/{action}/{id}", 
    new { controller = "Core", action = "Dashboard", id = UrlParameter.Optional } 
); 
+0

Voir mon commentaire ici: http://stackoverflow.com/questions/3321750/advanced-asp-net-mvc-routing-scenario Ne serait-il plus judicieux de stocker l'Organisation dans le session plutôt que sur la route? Comment allez-vous authentifier que vos utilisateurs n'essaient pas d'accéder à d'autres organisations? – Ryan

+0

Si vous me demandez, je n'aime pas votre solution d'un jeton en premier lieu. Le nom de l'organisation est un paramètre, tout comme l'ID d'un utilisateur. Vous modifiez John Doe avec un ID de 1 et de l'organisation Contoso. Je voudrais juste ajouter le paramètre d'organisation à la fin ou au milieu de votre route comme ceci: {controller}/{action}/{organisation}/{id}. Je définirais en fait les routes plus spécifiques par exemple, pour créer User/Create/{organisation} ou pour éditer User/Edit/{organisation}/{id}. De toute façon l'utilisation de l'organisation est seulement nécessaire si vous utilisez OrgID et UserID comme clé primaire composite – mare

+0

@Ryan nous fonctionnons sur Azure donc je devrais garder toutes les informations de session dans un cookie (pas terrible). Notre API applique déjà la sécurité à chaque appel, de sorte que les personnes qui devinent d'autres noms d'organisation (ou qui ont des doublons dans différents comptes) sont traitées. – Eric

Répondre

2

Url.Action utilise des valeurs de chaque voie pour de l'URL en interrogeant le fournisseur de chemin virtuel et de tenter de faire correspondre l'itinéraire le plus spécifique. Dans la forme que vous utilisez, vous fournissez des valeurs pour le contrôleur et l'action, qui est aussi profonde que la plupart des sites Web simples, d'où la forme pratique de la méthode. Lorsque Url.Action interroge le système de routage, il n'a qu'un segment "controller" et un segment "action" à faire correspondre.

Si vous donnez à la méthode le reste des informations de routage dont elle a besoin, elle correspondra correctement à l'itinéraire souhaité et renverra l'URL correcte.Essayez ceci:

Url.Action("User", "Create", new { token = "o", organization = "organization" }) 
+0

Ah, ça a marché! Donc, pour automatiser cela, une méthode d'extension sur UrlHelper serait-elle la meilleure? J'ai édité la question ci-dessus avec le code qui fonctionne. – Eric

Questions connexes