在 Routes mvc 4 中添加公司名称

Adding company name in Routes mvc 4

我一直在尝试为像 Facebook 这样的用户提供选项,让他们在 URL:

中添加他们的公司名称
http://localhost:50753/MyCompany/Login

我尝试了不同的 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 }
           );

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

谁能帮我弄清楚如何使用 MVC 路由来完成(如果可能,或者我的想法有误)?

问题是没有办法区分你的两条路线。例如 /a/b/c 可以是默认路由,company = a, controller = b, action = c 或者它可以是 Login 路由,controller = a, action = b, id = c.

要解决此问题,您需要设计路线,包括 AJAX 的路线,这样两条路线就不可能具有相同的 URL。在您的示例中,您可以将 /{id} 从登录路由中删除,因为它不需要。还要更具体地指定 URL 并将其放在默认值之前。这会给你类似

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

在这种情况下,/MyCompany/Login 和 /MyCompany/Login/Index 都会转到登录页面。但是 MyCompany/Home/Index 会转到 controller = Home,action = Index。

就个人而言,我倾向于完全删除默认路由,这样我就可以指定我想要的 URL,而不是将它们全部设为 /controller/action。这给了你更多的控制权,但也意味着单独指定每条路线。

您遇到的问题是因为这两个路由都匹配所有定义了 1、2 或 3 个段的 URL(因为控制器和操作具有默认值)。由于路由是按从顶部路由到底部路由的顺序执行的,因此您的顶部路由将 always 匹配,而您的底部路由 never 将匹配(除了用于主页)。

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

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

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

请注意,您可以实施 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 以了解如何创建自定义路由约束。

或者,如 Andy 所述,您可以通过明确指定 URL 的 1 个或多个片段来使匹配唯一。

url: "{companyName}/Login"

想法是必须有一些方法使您定义的第一条路线在某些情况下匹配。

或者,您可以实施 RouteBase,但仅当您需要比这个简单方案更多地控制匹配过程时才需要实施。