【问题标题】:How to map same routes for two controller?如何为两个控制器映射相同的路由?
【发布时间】:2016-01-16 20:29:36
【问题描述】:

我的 MVC 应用程序中有两个控制器。一个是Home 控制器,另一个是User 控制器。我正在使用以下 RouteConfig 设置。

routes.MapRoute(
            "actiononly",
            "{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

我想要abc.com/Blog abc.com/Login 而不是abc.com/Home/Blog abc.com/User/Login。 以上配置适用于abc.com/Blog,但不适用于abc.com/Login。 如何从两个控制器的链接中删除控制器名称? 另外,如何在网站启动时只显示abc.com 而不是abc.com/index?我在我的网页中使用以下代码来访问特定页面。

@Html.ActionLink("Home", "Blog", "Home")
@Html.ActionLink("Login", "Login", "User")

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 model-view-controller asp.net-mvc-routing


    【解决方案1】:

    您的默认路由应该自动满足想要导航到 abc.com 的需求,而不需要 URL 的 index 部分

    你需要确保你的主路由被指定为默认路由:

    context.MapRoute(
                "Site_Default",
                "{controller}/{action}/{*id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
    

    如果您想绘制短途路线,您可以完全按照上面的方法进行。我在自己的项目中使用这个辅助函数来映射短路径:

    void ShortRoute(string action, string controller)
    {
        ShortRoute(action, controller, action);
    }
    
    void ShortRoute(string action, string controller, string route)
    {
        _context.MapRoute(route, route, new { action, controller });
    }
    

    有用法:

    ShortRoute("About", "Home");
    

    这让我可以导航到 mywebsite.com/about 而不是 mywebsite.com/home/about

    如果它不适用于某些 URL,则可能是路由处理程序正在匹配不同的路由 - 我相信它确实取决于您注册它们的顺序

    有一个不错的路由调试插件可以用

    https://www.nuget.org/packages/routedebugger/

    它为您提供所有路由的摘要以及与当前 URL 匹配的路由 - 非常有用

    【讨论】:

    • 感谢查理的回复。几个问题。我在哪里添加ShortRoute 方法?在 RouteConfig 文件中?另外我在哪里打电话ShortRoute("About", "Home")?我在我的项目中添加了这个辅助方法,而不是我必须对所有操作都使用这个方法?
    【解决方案2】:

    无需引入额外的包裹,您只需添加额外的路线。要创建新路由,您首先必须定义您想要的 URL。在这种情况下,您已经说过您希望能够访问用户控制器上的/Login。好的 - 让我们创建一条新路线。此路线应位于您的默认路线上方

    routes.MapRoute(
                "UserLogin",
                "Login/{id}",
                new { controller = "User", action="Login", id = UrlParameter.Optional }
        );
    

    第一个参数只是路由名称。第二个参数是我希望此路由匹配的 URL 的格式。鉴于我们知道要与此路由匹配的操作,我们不需要默认路由中的 {action}{controller} 包罗万象的占位符。另请注意,我们可以声明此路由将访问哪个控制器,而无需在 URL 中指定控制器。

    最后一点,如果您永远不会将 ID 参数传递给该函数,则不必让 {id} 成为路由的一部分。如果是这种情况,那么您可以安全地删除 UserLogin 路由中对 id 的任何引用。

    当我重新阅读您的问题时,您也应该能够对其他一些示例执行此操作。让我们以/About URL 为例,演示如何删除{id} 参数。

    routes.MapRoute(
                "AboutUsPage",
                "About",
                new { controller = "Home", action="About"}
        );
    

    【讨论】:

    • 如果我在两个控制器中都有多个操作怎么办? Login/{id} 对其他操作无效。我该怎么做?
    • 正确,在某些时候,您将在路由中包含控制器名称,因为上述内容会变得不规则。我相信您也可以使用通配符映射。这实际上取决于您为什么需要您的 URL 以显示您想要的方式。有时,额外的工作可能不值得在 URL 中保存四个字符。
    【解决方案3】:

    非常简单。您只需为每个预期的 URL 创建一个路由。

    请记住,如果您不将控制器或操作作为 URL 占位符传递,则需要手动提供它们作为默认值。

    routes.MapRoute(
            "Blog",
            "Blog/{id}",
            new { controller = "Home", action = "Blog", id = UrlParameter.Optional }
        );
    routes.MapRoute(
            "Login",
            "Login/{id}",
            new { controller = "User", action = "Login", id = UrlParameter.Optional }
        );
    routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      • 2015-08-05
      • 2014-10-07
      • 1970-01-01
      • 2012-03-23
      • 2016-10-13
      • 2019-06-09
      相关资源
      最近更新 更多