Adding company name in Routes mvc 4

拈花ヽ惹草 提交于 2019-12-24 00:22:59

问题


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)?


回答1:


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.




回答2:


The problem is there is no way to distinguish between your two routes. For example /a/b/c could be the Default route with company = a, controller = b, action = c or it could be the Login route with controller = a, action = b, id = c.

To solve this you'll need to design your routes, including the ones for AJAX, so that there is no way two routes could have the same URL. In your example you could just drop the /{id} from the login route as it isn't needed. Also specify the URL more specifically and put it before the default. This would give you something like

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

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

In this case both /MyCompany/Login and /MyCompany/Login/Index would go to the login page. However MyCompany/Home/Index would go to controller = Home, action = Index.

Personally, I tend to remove the default route altogether so I can specify the URLs I want rather than have them all as /controller/action. That gives you more control but does mean specifying each route individually.



来源:https://stackoverflow.com/questions/28812432/adding-company-name-in-routes-mvc-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!