MVC EditorFor шаблоны, не используемые при вызове контроллера из другого контроллера

В проекте MVC у нас есть область с контроллером SomeController, возвращающим частичное представление, содержащее операторы EditorFor, каждый со своим собственным шаблоном.

Все работает нормально, если контроллер вызывается напрямую через маршрут для этой области. Однако, если он вызывается через другой контроллер за пределами области, то есть через 'new SomeController().SomeAction()', шаблоны не используются, даже если они явно указаны (представление возвращается в порядке, но показывает только текстовые поля по умолчанию и т. д.) .

В чем может быть причина этого и как это можно исправить?


person devlock    schedule 14.03.2016    source источник
comment
Где находятся ваши шаблоны (в /Views/Shared/EditorTemplates)?   -  person    schedule 14.03.2016
comment
Вы действительно инициализировали контроллер после new SomeController()? Для правильной работы требуется ControllerContext   -  person haim770    schedule 14.03.2016
comment
@Stephen Muecke: они находятся в Area//Views/Some/EditorTemplates и обнаруживаются нормально, если контроллер вызывается напрямую   -  person devlock    schedule 14.03.2016
comment
@ haim770: что именно ты имеешь в виду? Контроллер в этой области вызывается с помощью 'new SomeController().SomeAction()', должен ли я передать что-то еще?   -  person devlock    schedule 14.03.2016
comment
Если вы поместите их в папку /Views/Shared/EditorTemplates, они должны быть найдены всеми контроллерами.   -  person    schedule 14.03.2016
comment
@devlock, когда задействован ViewResult, вам лучше использовать ControllerFactory / ActionInvoker, чтобы правильно имитировать обычное поведение.   -  person haim770    schedule 14.03.2016
comment
да, их можно найти, когда они находятся в режиме просмотра/совместного использования, но с организационной точки зрения они действительно принадлежат этой области, поэтому, если возможно, они должны оставаться там; Я также хотел бы понять, почему они не используются в этом сценарии (в конце концов, это контроллер области, возвращающий вид)   -  person devlock    schedule 14.03.2016


Ответы (1)


Когда ваше действие вызывается просто с использованием ctrl.Action(), будет использоваться текущий RouteData (с текущими значениями area/controller/action в нем), и когда Razor пытается разрешить ваши EditorTemplates пути, он обращается к ViewContext, который все еще содержит (теперь неправильные) значения исходного действие.

Вам лучше использовать ControllerFactory, чтобы имитировать желаемое поведение:

var ctrlFactory = ControllerBuilder.Current.GetControllerFactory();

var routeData = new RouteData();
routeData.DataTokens.Add("area", "target_area_name");
routeData.Values.Add("controller", "target_controller_name");
routeData.Values.Add("action", "target_action_name");

var requestContext = new RequestContext(this.HttpContext, routeData);
var ctrl = ctrlFactory.CreateController(requestContext, "target_controller_name") as TargetControllerType;

if (ctrl != null)
{
    ctrl.ControllerContext = new ControllerContext(requestContext, ctrl);

    var ctrlDesc = new ReflectedControllerDescriptor(typeof(TargetControllerType));
    var actionDesc = ctrlDesc.FindAction(ctrl.ControllerContext, "target_action_name");

    var result = actionDesc.Execute(ctrl.ControllerContext, new Dictionary<string, object>()) as ActionResult;

    this.RouteData.DataTokens["area"] = "target_area_name";
    this.RouteData.Values["controller"] = "target_controller_name";
    this.RouteData.Values["action"] = "target_action_name";

    return result;
}

См. MSDN.

person haim770    schedule 14.03.2016
comment
Я впечатлен этим фрагментом, он тоже работает, но, к сожалению, результат тот же (шаблоны игнорируются) - person devlock; 14.03.2016
comment
@devlock, Вы ввели правильные значения для area, controller и action? - person haim770; 14.03.2016
comment
Я так полагаю, действие контроллера выполняется без проблем, просто шаблоны не отрисовываются - person devlock; 14.03.2016
comment
@devlock, я обновил ответ. Теперь это немного менее элегантно, но должно работать. - person haim770; 14.03.2016