【问题标题】:How to call controller action with a routeValue parameter in ASP.NET MVC如何在 ASP.NET MVC 中使用 routeValue 参数调用控制器操作
【发布时间】:2020-06-17 03:44:45
【问题描述】:

我有以下@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
    );   

【问题讨论】:

  • 请出示您的 routeconfig 文件
  • 基本上这会调用 Widget 控制器的 Widget 动作,其中 wAction = "GetWorldMapMethod" 是路由数据。我希望您的代码在操作方法中处理此参数并做出相应的决定。分享控制器代码以获得更准确的答案
  • 是的,控制器具有操作方法“Widget”和“GetWorldMapMethod”,因此在调用方法“GetWorldMapMethod”之后调用加载方法“Widget”。我的问题是如何调用“GetWorldMapMethod”方法。
  • 好吧,这些块有什么问题,或者您只是想知道 RenderAction 扩展是如何工作的?
  • @gurkan:我读到的是 OP 继承了这段代码,并试图了解它是如何工作的,因为没有明显的理由调用 GetWorldMapMethod()

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


【解决方案1】:

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

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


完整答案

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

子动作路由

首先,重要的是要注意虽然@AbdulG 要求您提供RouteConfig 的详细信息,但它们在这里并不真正相关。 @Html.RenderAction() 需要 actionName 参数,并且可以选择接受 controllerName,从而绕过您设置的任何路由。事实上,因为RenderAction()是为了渲染一个child action,所以它@98​​7654322@。

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

注意: 有一些高级场景——such as implementing a custom IControllerFactory——这个假设可能不正确,所以你应该确认不存在例如。在您的Global.asax.cs 中注册SetControllerFactory()。如果有,它可能会拦截请求并将其路由到单独的操作。

路由数据处理

第二,this @Html.RenderHtml() overload的第三个参数代表你的routeValues。因此Widget() 操作——以及任何中间代码,例如IControllerFactory 或任何action filters——将有权访问这些值,以实现他们认为合适的任何业务逻辑。 这可能包括调用不同的操作

鉴于此,我的假设是在这条管道的某个地方,会有如下代码:

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

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

注意:这只是一个例子。有几十种不同的方法可以评估RouteData 的内容并对其做出响应,包括例如反射。不过,如果您在代码库中搜索 wAction,这应该有助于您隔离处理该路由值的代码。

调试

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

结论

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

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

【讨论】:

  • 顺便说一句,我假设您从以前的开发人员那里继承了这个代码库,他们不来回答问题。如果是这样,你肯定有我的同情!作为一名顾问,我用最少的文档继承了相当多的遗留代码库,这需要大量的逆向工程来了解各个部分的连接方式。如果他们依赖于更高级的功能,这可能会变得特别复杂,如果您不知道在哪里寻找它,这可能不会立即显现出来。
  • 另外值得注意的是,路由在 ASP.NET Core 中更加明确,其中 RenderAction() 已被删除,有利于 View Components。视图组件类似于局部视图的微型 MVC,因此操作类似于RenderAction()。在那里,您通过名称显式调用视图组件,因此不会混淆路由。 (尽管它们仍然会被 IViewComponentActivator 拦截,其作用类似于 ASP.NET MVC 中的 IControllerFactory。)
  • 谢谢杰里米·卡尼
猜你喜欢
  • 1970-01-01
  • 2011-09-01
  • 2010-11-27
  • 1970-01-01
  • 2011-02-14
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
相关资源
最近更新 更多