How to use RenderAction with custom Routing?

不问归期 提交于 2021-02-08 11:14:13

问题


we are starting to use routes for our MVC project, so we basicly replace ActionLink() with RouteLink() - now we want to replace RenderAction() to add route information we need (mainly the routename)...

Here is one of our mappings:

 // 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;

So with RenderAction(controller, action) we have half of the information, what we need is the routename or name or whatever it is called in the method to assign "tool" in "tool/controller/action".


回答1:


we are starting to use routes for our MVC project, so we basicly replace ActionLink() with RouteLink()

Not sure if you realize that one has nothing to do with the other. ActionLink and RouteLink end up calling the exact same method on the UrlHelper. The only difference is that ActionLink sends a null value for route name.

When specifying a route name, only 1 route will be checked to see if it matches the request. Otherwise, all of the routes will be checked in the order they are registered in the route table. The first matching route wins.

The route name is (as would be implied) the name of the route.

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

That said, it is unclear from your question what you are trying to achieve. Normally, you would use a literal segment in a route to use default route values that only apply to a specific route.

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

In this case, the tool segment in the URL force it to only match URLs beginning with /tool. It also means there is no way to override the default setting of controller = "Tool". But do note that the literal URL has absolutely nothing to do with what is put into the route value dictionary during the request.

Also, you seem to be defeating the purpose of using namespaces by setting the namespaces argument of the route and then setting UseNamespaceFallback to false. Unless your application is explicitly using the namespaces in some way, this is senseless.

As for RenderAction, the framework uses controller and action to lookup the child action to render, and passes any values you provide to the method. It builds a new HttpRequest and then executes it as if you were coming in under that set of route values. As far as routing is concerned, this only matters if you have calls to ActionLink, RouteLink, etc. on the view that is rendered (or in any filters that may be in the pipeline on that action). Other than that, this fake request doesn't actually hit the route table. See this post for detailed information about how to use RenderAction.




回答2:


You're confusing two unrelated ideas. Granted MVC itself is a bit confused here as well, which is why in MVC 6, they've dropped child actions and created "view components" instead.

Simply, child actions (which is what you're utilizing when you call RenderAction) utilize the routing infrastructure, but they aren't true actions and aren't typically exposed to the outside worlds as routes. In other words, the URL generated internally to get at the child action doesn't actually matter, as long as it gets to the action. As a result, you don't need your custom Tool route for a child action. You just need a controller and action and the default route will be enough to get you there. This is why there's no Html.RenderRoute or Html.Route actions to correspond with Html.RenderAction and Html.Action. There's no need.

Now, the way routing works is that all the controllers in the project are pull in and then based on the route, one is picked from that set that matches best. By separating out your controllers into different namespaces, you can technically reuse controller names within each namespace, but then you must specify the namespaces for any route in order to narrow the choices down to the right controller/action pair, which is why I think you're feeling the need to use custom routes here. I don't really do this myself, but I think you should be able to pass the namespace as a route value:

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


来源:https://stackoverflow.com/questions/37541282/how-to-use-renderaction-with-custom-routing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!