如何在自定义路由中使用RenderAction?

时间:2016-05-31 09:02:39

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

我们开始为MVC项目使用路由,所以我们基本上用ActionLink()替换ActionLink() - 现在我们要替换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(控制器,操作),我们有一半的信息,我们需要的是路由名称或名称或在“工具/控制器/操作”中分配“工具”的方法中调用的任何信息。

2 个答案:

答案 0 :(得分:0)

  

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

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

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

路线名称是(视为暗示)路线的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" });

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

此外,您似乎通过设置路由的名称空间参数,然后将UseNamespaceFallback设置为false来破坏使用名称空间的目的。除非您的应用程序以某种方式明确使用命名空间,否则这是毫无意义的。

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

答案 1 :(得分:0)

你混淆了两个不相干的想法。授予MVC本身也有点困惑,这就是为什么在MVC 6中,他们放弃了子动作并改为创建了“视图组件”。

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

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

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