在Routes mvc 4中添加公司名称

Sal*_*man 3 c# asp.net-mvc asp.net-mvc-routing

我一直在努力为Facebook这样的用户提供选项,以便在URL中添加他们的公司名称:

http://localhost:50753/MyCompany/Login
Run Code Online (Sandbox Code Playgroud)

我尝试了不同的URL,但它没有用.

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 }
           );
Run Code Online (Sandbox Code Playgroud)

现在,当我添加此路由以使其工作时,我的所有AJAX请求都会失败,而那些成功代表HTML而不是JSON.我注意到的是,由于这条路线,我的页面再次重新加载.

有人可以帮我弄清楚如何使用MVC路由(如果有可能,或者我是以错误的方式思考)?

Nig*_*888 7

您遇到的问题是由于这两个路由都匹配定义了1,2或3个段的所有URL(因为控制器和操作具有默认值).由于路线按照从最高路线到最低路线的顺序执行,因此您的最高路线将始终匹配,您的最低路线永远不会匹配(主页除外).

由于顶部路由始终匹配,因此假设第一个段是控制器而第二个段是操作的URL将失败,因为您将这些值分别放入companyNamecontroller路由键中.

为了使其按预期工作,您需要创建一个知道所有公司名称的路由约束.

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

请注意,您可以实现IRouteConstraint这样,您可以从缓存的数据库模型中提取值以匹配,而不是将它们硬编码到配置中.请参阅此文章以了解如何创建自定义路由约束.

或者,正如Andy所提到的,您可以通过明确指定URL的一个或多个段来使匹配唯一.

url: "{companyName}/Login"
Run Code Online (Sandbox Code Playgroud)

这个想法是必须有某种方法使你定义的第一条路线在某些情况下匹配.

或者,您可以实现RouteBase,但只需要比这个简单的场景更需要对匹配过程的控制.