ASP.NET MVC以编程方式初始化Controller并调用操作

时间:2015-03-10 15:22:13

标签: c# asp.net-mvc asp.net-mvc-4

我正在构建一个预定的作业控制器 - 这些作业将调用控制器操作捕获结果。我宁愿在后端发生所有这些,也不要涉及http调用。

类似于单元测试的情况 - 例如:

var controller = new TestController();
var result = controller.Index("TestParameter") as ViewResult;

问题在于此示例中控制器和操作不是动态的,是否有人知道如何初始化控制器并使用控制器的名称和操作作为字符串参数调用操作?如 -

public ActionResult run(string controllerName, string actionName)
{
    var controller = new Controller(controllerName);
    var result = controller.action(actionName).("TestParameter") as ViewResult;
    return Content(result);
}

2 个答案:

答案 0 :(得分:14)

使用ControllerFactoryActionDescriptor动态执行操作:

public ActionResult Run(string controllerName, string actionName)
{
    // get the controller
    var ctrlFactory = ControllerBuilder.Current.GetControllerFactory();
    var ctrl = ctrlFactory.CreateController(this.Request.RequestContext, controllerName) as Controller;
    var ctrlContext = new ControllerContext(this.Request.RequestContext, ctrl);
    var ctrlDesc = new ReflectedControllerDescriptor(ctrl.GetType());

    // get the action
    var actionDesc = ctrlDesc.FindAction(ctrlContext, actionName);

    // execute
    var result = actionDesc.Execute(ctrlContext, new Dictionary<string, object>
    {
        { "parameterName", "TestParameter" }
    }) as ActionResult;

    // return the other action result as the current action result
    return result;
}

请参阅MSDN

答案 1 :(得分:-3)

我不确定您的真正问题在哪里 - 您想测试控制器/操作还是要测试作业的功能?

  1. 如果您需要测试控制器/操作,则会涉及HttpContext
  2. 如果您需要更好地测试工作功能,可以将服务/存储库层中的内容分开,并且可以使用存储库模式进行测试。