views:

182

answers:

1

Currently, I have URLs that look like this:

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

But now, I have to support multiple organizations and their users. I need to have something like this:

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

I was having trouble getting the routes to work just perfectly, so I had to add a token to the beginning of the organization name so that routing wouldn't confuse it with a controller/action pair. Not a huge deal but my URLs look like this now:

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

That's fine. I can live with that.

Here's where I'm running into trouble:
When I generate URLs once I have an organization selected, it's not persisting the organization name. So when I'm here:

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

...and I use Url.Action("User", "Create") to generate a URL, it outputs:

/user/create

...rather than what I want:

/o/org-name/user/create

This is what my routes look like (in order):

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

It's similar to this question ASP.NET MVC Custom Routing Long Custom Route not Clicking in my Head.

I have a feeling this is going to end up being obvious but it's Friday and it's not happening right now.


EDIT:
Womp's suggested worked but would this be the best way to automate this?

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:
Fixed my routes to work rather than hacking it together. The final solution didn't need the stupid {token} in the URL. Maybe this'll help someone else:

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 }
);
+2  A: 

Url.Action uses route values to generate the actual URL's by querying the virtual path provider and attempting to match the most specific route. In the form that you are using, you are supplying values for the controller and the action, which is as deep as most simple websites go, hence the convenient form of the method. When Url.Action queries the routing system, it only has a "controller" and an "action" segment to match.

If you give the method the rest of the routing information it needs, it will properly match the route that you desire, and will return the correct URL. Try this:

Url.Action("User", "Create", new { token = "o", organization = "organization" })
womp
Ah ha, that worked!So to automate this, would a extension method on UrlHelper be best? I edited the question above with the code that works.
Eric Willis