Как вызвать действие контроллера с параметром routeValue в ASP. NET MVC - PullRequest
2 голосов
/ 17 июня 2020

У меня есть существующий код с методом @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
    );   

1 Ответ

1 голос
/ 26 июня 2020

TL; DR @Html.RenderAction() не зависит от ваших маршрутов. Он попытается напрямую вызвать действие WidgetController.Widget(). Это действие, а также любой промежуточный код, такой как IControllerFactory или IActionFilter, может использовать ваш routeValues словарь, чтобы оценить вашу настраиваемую переменную маршрута wAction и ответить соответствующим образом. Это может включать вызов вашего действия WidgetController.GetWorldMapMethod().

Крайне важно, ASP. NET MVC не выполняет маршрутизацию и не вызывает ваш GetWorldMapMethod(); вместо этого он запускается чем-то в вашем коде .

Полный ответ

Как отмечает @Always_a_learner в комментариях, без доступа к коду вашего контроллера мы не можем дать точный ответ. Тем не менее, мы можем по крайней мере предоставить некоторую справочную информацию и связать ее с обоснованным предположением о том, что может происходить.

Маршрутизация дочерних действий

Во-первых, это Важно отметить, что хотя @AbdulG запросил ваши RouteConfig данные, они здесь не актуальны. @Html.RenderAction() требует параметра actionName и, необязательно, принимает controllerName, таким образом обходя любые настроенные вами маршруты. Фактически, поскольку RenderAction() предназначен для рендеринга дочернего действия , не имеет смысла иметь связанный с ним маршрут publi c .

Учитывая, что, независимо от вашей конфигурации MapRoute(), мы можем быть уверены, что ваш вызов @Html.RenderAction() сначала попытается выполнить действие с именем WidgetController.Widget().

Примечание: Существуют расширенные сценарии - , такие как реализация пользовательского IControllerFactory - где это предположение может быть неверным, поэтому вы должны подтвердить, что нет, например, SetControllerFactory() регистрация в вашем Global.asax.cs. Если есть, он потенциально может перехватить запрос и направить его в отдельное действие.

Обработка данных маршрута

Во-вторых, третий параметр this @Html.RenderHtml() overload представляет ваш routeValues. Таким образом, действие Widget(), а также любой промежуточный код, такой как IControllerFactory или любые фильтры действий , будут иметь доступ к этим значениям для реализации любых бизнес-логик c, которые они сочтут соответствующий. Это может потенциально включать вызов другого действия .

Учитывая это, я предполагаю, что где-то в этом конвейере будет код, который выглядит примерно так:

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

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

Примечание: Это просто пример. Существуют десятки различных подходов к оценке содержимого RouteData и реагированию на него, включая, например, отражение. Тем не менее, если вы ищете wAction в базе кода, это должно помочь вам определить, какой код обрабатывает это значение маршрута.

Отладка

Если вы используете IDE как и Visual Studio, самым простым решением было бы запустить отладчик, добавить точку останова к вашему вызову @Html.RenderAction() и пройти через конвейер выполнения. Это откроет доступ к любой расширенной функциональности, такой как применяемый промежуточный код IControllerFactory или IActionFilter, а также позволит вам точно определить, когда и где код вызывает ваше действие GetWorldMapMethod().

Заключение

Как отмечено вверху, я боюсь, что я не могу дать конкретный ответ на то, как именно ваш GetWorldMapMethod() получает вызов, на основе предоставленной информации. Но, надеюсь, этот ответ предоставит вам solid достаточную основу для понимания переменных и обратного проектирования базы кода, с которой вы работаете.

Если вы можете продолжить работу с кодом своего контроллера, я Буду рад дополнить этот ответ более подробным c руководством.

...