ASP.NET MVC 2 Маршрутизация с дополнительными непротиворечивыми параметрами (не только контроллер и действие) - PullRequest
3 голосов
/ 23 июля 2010

В настоящее время у меня есть URL, которые выглядят так:

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

Но теперь я должен поддержать несколько организаций и их пользователей. Мне нужно что-то вроде этого:

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

У меня были проблемы с тем, чтобы маршруты работали просто идеально, поэтому мне пришлось добавить токен в начало названия организации, чтобы маршрутизация не перепутала его с парой контроллер / действие. Ничего страшного, но мои URL теперь выглядят так:

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

Отлично. Я могу жить с этим.

Вот где у меня проблемы:
Когда я генерирую URL-адреса после выбора организации, она не сохраняет название организации. Поэтому, когда я здесь:

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

... и я использую Url.Action («Пользователь», «Создать») для генерации URL, он выводит:

/user/create

... а не то, что я хочу:

/o/org-name/user/create

Вот так выглядят мои маршруты (по порядку):

        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 }
        );

Это похоже на этот вопрос ASP.NET MVC Custom Routing Long Custom Route не щелкает в моей голове .

У меня такое чувство, что это станет очевидным, но сейчас пятница, и сейчас этого не происходит.


РЕДАКТИРОВАТЬ:
Предложенный Womp работал, но будет ли это лучшим способом автоматизировать это?

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;
    }


РЕДАКТИРОВАТЬ:
Исправлены мои маршруты, чтобы работать вместо того, чтобы взламывать его вместе. Окончательное решение не нуждалось в глупом {токене} в URL. Может быть, это поможет кому-то еще:

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 }
);

1 Ответ

2 голосов
/ 23 июля 2010

Url.Action использует значения маршрута для создания фактических URL-адресов, запрашивая поставщика виртуального пути и пытаясь сопоставить наиболее конкретный маршрут.В той форме, которую вы используете, вы задаете значения для контроллера и действия, столь же глубокого, как и большинство простых веб-сайтов, и, следовательно, удобную форму метода.Когда Url.Action запрашивает систему маршрутизации, он имеет только соответствующий «контроллер» и «действие» сегмента.

Если вы передадите методу остальную необходимую ему информацию о маршрутизации, он будет правильно соответствоватьмаршрут, который вы хотите, и вернет правильный URL.Попробуйте это:

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