MVC EditorFor 从另一个控制器调用控制器时不使用的模板
MVC EditorFor templates not used when calling controller from another controller
在 MVC 项目中,我们有一个区域,其中有一个控制器 SomeController 返回一个部分视图,其中包含 EditorFor 语句,每个语句都有自己的模板。
如果通过该区域的路线直接调用控制器,一切正常。但是,如果它是通过区域外的另一个控制器调用的,即通过 'new SomeController().SomeAction()',则不会使用模板,即使明确指定(视图返回正常,但仅显示默认文本框等)。
这可能是什么原因,如何解决?
当仅使用 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
在 MVC 项目中,我们有一个区域,其中有一个控制器 SomeController 返回一个部分视图,其中包含 EditorFor 语句,每个语句都有自己的模板。
如果通过该区域的路线直接调用控制器,一切正常。但是,如果它是通过区域外的另一个控制器调用的,即通过 'new SomeController().SomeAction()',则不会使用模板,即使明确指定(视图返回正常,但仅显示默认文本框等)。
这可能是什么原因,如何解决?
当仅使用 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