如何在 ASP.NET MVC 中使用 routeValue 参数调用控制器操作

How to call controller action with a routeValue parameter in ASP.NET MVC

我有以下 @html.RenderAction() 方法的现有代码:

Html.RenderAction("Widget", "Widget", new
{
    wTitle = "World map dashboard",
    wTitleSpan = "",
    wTitleDisplay = "",
    height = "300px;",
    wAction = "GetWorldMapMethod",
    wCssId = "WorldMap",
    cssOptions = "WorldMap",
    ShipSelection = "fleet",
    infoTitle = HttpUtility.HtmlEncode("<b>Info dashboard</b>"),
    infoText = HttpUtility.HtmlEncode("<p>Info</p>")
});

执行此操作时,将调用方法GetWorldMapMethod()。我正在尝试了解如何调用此参数操作方法。

这是我的路由配置:

routes.MapRoute(
    "ManagementShipDetails",
    "Management/ShipDetails/{id}/{successMessage}",
    new {controller = "Management", action = "ShipDetails", successMessage = UrlParameter.Optional}
    );

routes.MapRoute(
    "Report",
    "Data/Report/{viewname}",
    new
    {
        controller = "Data",
        action = "Report",
    });

routes.MapRoute(
    "Apikeydelete",
    "Account/DeleteApiKey/{key}",
    new {controller = "Account", action = "DeleteApiKey"}
    );

routes.MapRoute(
    "FleetOverview",
    "Fleet",
    new {controller = "Data", action = "Fleet"}
    );

routes.MapRoute(
    "ShipOverview",
    "{ShipName}/Overview",
    new {controller = "Data", action = "Overview", ShipName = UrlParameter.Optional}
    );

routes.MapRoute(
    "Hull Performance",
    "{ShipName}/HullPerformanceDrop",
    new {controller = "Data", action = "HullPerformanceDrop", ShipName = UrlParameter.Optional}
    );

routes.MapRoute(
    "ReportingViewReport",
    "{ShipName}/Report/{id}",
    new
    {
        controller = "Reporting",
        action = "Report",
        ShipName = UrlParameter.Optional,
        id = UrlParameter.Optional
    }
    );

routes.MapRoute(
    "PortalDataGetValue",
    "PortalData/GetValue/{tag}/{selection}/{date}/{Filter}",
    new {controller = "PortalData", action = "GetValue", Filter = UrlParameter.Optional}
    );

routes.MapRoute(
    "PortalDataGetDashboardData",
    "PortalData/GetDashboardData/{selection}/{date}",
    new {controller = "PortalData", action = "GetDashboardData", Filter = UrlParameter.Optional}
    );

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new {controller = "Dashboards", action = "Index", id = UrlParameter.Optional} // Parameter defaults
    );   

TL;DR @Html.RenderAction() 不依赖于您的路线。它将尝试直接调用 WidgetController.Widget() 操作。该操作——以及任何中间代码,例如 IControllerFactoryIActionFilter——可以使用您的 routeValues 字典来评估您的自定义 wAction 路由变量并做出适当的响应。这可能包括调用您的 WidgetController.GetWorldMapMethod() 操作。

严重的是,ASP.NET MVC 没有路由到或调用您的 GetWorldMapMethod();它是由您的代码中的某些内容触发的 .


完整答案

正如@Always_a_learner 在评论中指出的那样,在无法访问您的控制器代码的情况下,我们无法提供准确的答案。也就是说,我们至少可以提供一些背景信息,并将其与关于 可能 会发生什么的有根据的猜测配对。

子操作路由

首先,重要的是要注意,虽然@AbdulG 要求您提供 RouteConfig 详细信息,但它们在这里并不真正相关。 @Html.RenderAction() 需要一个 actionName 参数,并且可以选择接受一个 controllerName,从而绕过您设置的任何路由。事实上,因为 RenderAction() 的目的是渲染一个 child action, it doesn't make sense to have a public route associated with it.

鉴于此,独立于您的 MapRoute() 配置,我们可以确信您对 @Html.RenderAction() 的调用将首先尝试执行名为 WidgetController.Widget().[=45 的操作=]

Note: There are advanced scenarios—such as implementing a custom IControllerFactory—where this assumption might not be true, so you should confirm that there isn't e.g. a SetControllerFactory() registration in your Global.asax.cs. If there is, it could potentially intercept the request and route it to a separate action.

路由数据处理

其次,this @Html.RenderHtml() overload represents your routeValues. So the Widget() action—as well as any intermediate code, such as an IControllerFactory, or any action filters 的第三个参数 - 将有权访问这些值,以便实施他们认为合适的任何业务逻辑。 这可能包括调用不同的操作

鉴于此,我的假设是在此管道中的某处,会有如下所示的代码:

var wAction = ControllerContext.RouteData.GetRequiresString("wAction");

switch (wAction) {
  case "GetWorldMapMethod":
    GetWorldMapMethod();
    break;
  default:
    break;
}

Note: This is just an example. There are dozens of different approaches for evaluating the contents of the RouteData and responding to it, including e.g. reflection. Still, if you search for wAction in your code base, that should help you isolate what code is handling that route value.

调试

如果您正在使用 IDE,例如 Visual Studio,最简单的解决方案是启动调试器,向 @Html.RenderAction() 调用添加断点,然后单步执行执行管道。这将公开任何高级功能——例如正在应用的中间 IControllerFactoryIActionFilter 代码——并且还允许您准确识别代码调用您的 GetWorldMapMethod() 操作的时间和位置。

结论

如顶部所述,恐怕我无法根据所提供的信息准确回答您的 GetWorldMapMethod() 是如何被调用的。但是,希望这个答案将为您提供足够坚实的基础来理解变量并对您正在使用的代码库进行逆向工程。

如果您可以跟进您的控制器代码,我也很乐意更新此答案并提供更具体的指导。