【问题标题】:How to use RenderAction with custom Routing?如何将 RenderAction 与自定义路由一起使用?
【发布时间】:2016-05-31 22:00:03
【问题描述】:

我们开始为我们的 MVC 项目使用路由,所以我们基本上将 ActionLink() 替换为 RouteLink() - 现在我们要替换 RenderAction() 以添加我们需要的路由信息​​(主要是路由名称)...

这是我们的映射之一:

 // Route für Tools
        route = routes.MapRoute(
            name: "Tool",
            url: "tool/{controller}/{action}",
            defaults: new { controller = "Home", action = "Index" },
            namespaces: new[] { "Web.Controllers.Tool" });
        route.DataTokens["UseNamespaceFallback"] = false;

所以使用 RenderAction(controller, action) 我们有一半的信息,我们需要的是路由名称或名称或在方法中调用的任何内容,以便在“工具/控制器/操作”中分配“工具”。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-routing


    【解决方案1】:

    我们开始在 MVC 项目中使用路由,所以我们基本上将 ActionLink() 替换为 RouteLink()

    不确定您是否意识到其中一个与另一个无关。 ActionLinkRouteLink 最终在 UrlHelper 上调用完全相同的方法。唯一的区别是ActionLink 发送一个null 值作为路由名称。

    指定路由名称时,只会检查 1 条路由是否匹配请求。否则,将按照它们在路由表中注册的顺序检查所有路由。第一个匹配的路线获胜。

    路由名称是(暗示的)路由的name

    var url = Url.RouteUrl("Tool", new { controller = "Tool", action = "Index" });
    

    也就是说,您的问题尚不清楚您要达到的目标。通常,您会在路由中使用文字段来使用仅适用于特定路由的默认路由值。

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

    在这种情况下,URL 中的工具段强制它只匹配以/tool 开头的 URL。这也意味着无法覆盖controller = "Tool" 的默认设置。但请注意,文字 URL 与请求期间放入路由值字典的内容绝对无关。

    此外,通过设置路由的命名空间参数,然后将UseNamespaceFallback 设置为false,您似乎违背了使用命名空间的目的。除非您的应用程序以某种方式显式使用命名空间,否则这是没有意义的。

    对于RenderAction,框架使用controlleraction 来查找要渲染的子操作,并将您提供的任何值传递给方法。它构建了一个新的HttpRequest,然后执行它,就好像您在该组路由值下进入一样。就路由而言,仅当您在呈现的视图上调用ActionLinkRouteLink 等时(或在该操作的管道中可能存在的任何filters 中),这才重要。除此之外,这个虚假请求实际上并没有命中路由表。有关如何使用RenderAction 的详细信息,请参阅this post

    【讨论】:

      【解决方案2】:

      您混淆了两个不相关的想法。当然,MVC 本身在这里也有些混乱,这就是为什么在 MVC 6 中,他们放弃了子操作并创建了“视图组件”。

      简单地说,子操作(当您调用 RenderAction 时正在使用该操作)利用路由基础架构,但它们不是真正的操作,并且通常不会作为路由暴露给外部世界。换句话说,内部生成的用于获取子操作的 URL 实际上并不重要,只要它获取到操作即可。因此,您不需要自定义 Tool 路由来执行子操作。你只需要一个控制器和一个动作,默认路由就足以让你到达那里。这就是为什么没有与Html.RenderActionHtml.Action 对应的Html.RenderRouteHtml.Route 操作。没必要。

      现在,路由的工作方式是拉入项目中的所有控制器,然后根据路由,从最匹配的集合中挑选一个。通过将控制器分离到不同的命名空间中,您可以在技术上重用每个命名空间中的控制器名称,但是您必须为任何路由指定命名空间,以便将选择范围缩小到正确的控制器/动作对,这就是我认为您的原因'感觉有必要在这里使用自定义路线。我自己并没有真正这样做,但我认为您应该能够将命名空间作为路由值传递:

      @Html.Action("Action", "Controller", new { namespace = "Web.Controllers.Tool" })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 2021-09-02
        • 2018-11-14
        • 2016-05-26
        • 2017-11-09
        • 2021-05-25
        • 1970-01-01
        相关资源
        最近更新 更多