Search code examples
c#asp.net-mvcasp.net-mvc-routing

Adding company name in Routes mvc 4


I have been trying to give options to users like Facebook to add their company name in the URL:

http://localhost:50753/MyCompany/Login

I have tried different URLs, but it didn't work.

routes.MapRoute(
                name: "Default",
                url: "{companyName}/{controller}/{action}",
                defaults: new { controller = "Login", action = "Index"}
            );

routes.MapRoute(
               name: "Login",
               url: "{controller}/{action}/{id}",
               defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
           );

Now when I add this route to get it work, all of my AJAX requests start fails and those that succeed represent HTML rather than JSON. What I have noticed is that because of this route, my page gets reload again.

Can someone help me figure out how can it be done using MVC routing (if it's possible, or if I'm thinking in the wrong way)?


Solution

  • The problem you are having is due to the fact that both of these routes will match all URLs that have 1, 2, or 3 segments defined (because the controller and action have default values). Since routes are executed in order from the top route to the bottom route, your top route will always match and your bottom route never will match (except for the home page).

    Since the top route always matches, URLs that assume that the first segment is the controller and the second segment is the action will fail because you are putting these values into the companyName and controller route keys, respectively.

    For this to work as you expect, you need to make a route constraint that is aware of all of the company names.

    routes.MapRoute(
                name: "Default",
                url: "{companyName}/{controller}/{action}",
                defaults: new { controller = "Login", action = "Index"},
                constraints: new { companyName = "Company1|Comany2|Company3" }
            );
    

    Note that you could implement IRouteConstraint so you could pull the values to match from a cached database model instead of hard-coding them into the configuration. See this post to learn how to create a custom route constraint.

    Or, as Andy mentioned, you can make the match unique by specifying 1 or more segments of the URL explicitly.

    url: "{companyName}/Login"
    

    The idea is there must be some way to make the first route you defined not match in certain cases.

    Alternatively, you could implement RouteBase, but you would only need to if you require much more control over the matching process than this simple scenario.