如何从 Mvc 中的控制器调用另一个控制器操作

我需要从 Controller A 调用控制器 B 操作 FileUploadMsgView,并需要为它传递一个参数。

它不会进入控制器 B 的 FileUploadMsgView()

密码是这样的:

控制员 A:

private void Test()
{
try
{   //some codes here
ViewBag.FileUploadMsg = "File uploaded successfully.";
ViewBag.FileUploadFlag = "2";
RedirectToAction("B", "FileUploadMsgView", new { FileUploadMsg = "File   uploaded successfully" });
}
}

控制员 B (接收部分) :

public ActionResult FileUploadMsgView(string FileUploadMsg)
{
return View();
}
414719 次浏览

控制器只是类——新的类,调用 action 方法,就像你调用其他类成员一样:

var result = new ControllerB().FileUploadMsgView("some string");

您的示例看起来像 psuedo 代码。您需要 返回RedirectToAction的结果:

return RedirectToAction("B",
"FileUploadMsgView",
new { FileUploadMsg = "File uploaded successfully" });

正如@mx 导弹在对已接受答案的评论中所说的那样,您不应该更新控制器,因为它将缺少为 IoC 设置的依赖关系,而且不会有 HttpContext

相反,您应该得到一个控制器的实例,如下所示:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);

这正是我在发现 RedirectToAction()不会传递复杂类对象后所寻找的。

作为一个示例,我想调用 LifeCycleEffectsResults控制器中的 IndexComparison方法,并将一个名为 model 的复杂类对象传递给它。

以下是失败的代码:

return RedirectToAction("IndexComparison", "LifeCycleEffectsResults", model);

值得注意的是,String、整数等在这个控制器方法之旅中幸存了下来,但是泛型列表对象却遭受了类似于 C 内存泄漏的问题。

正如上面推荐的那样,下面是我替换它的代码:

var controller = DependencyResolver.Current.GetService<LifeCycleEffectsResultsController>();


var result = controller.IndexComparison(model);
return result;

现在一切正常,谢谢你带路。

就像@DLeh 说的 使用宁可

var controller = DependencyResolver.Current.GetService<ControllerB>();

但是,对于控制器,控制器上下文非常重要,特别是当您需要访问“子”控制器中的 User对象、 Server对象或 HttpContext时。

我添加了一行代码:

controller.ControllerContext = new ControllerContext(Request.RequestContext, controller);

或者你可以使用系统。Web 也可以访问当前上下文,以访问 Server或早期提到的对象

注意: 我的目标是框架版本4.6(Mvc5)

让解析器自动完成这项工作。

控制器内部:

public class AController : ApiController
{
private readonly BController _bController;


public AController(
BController bController)
{
_bController = bController;
}


public httpMethod{
var result =  _bController.OtherMethodBController(parameters);
....
}


}

如果问题是打电话。 您可以使用此方法调用它。

yourController obj= new yourController();


obj.yourAction();

Dleh 的回答 是正确的,并解释了如何获取另一个控制器的实例,而不会丢失为 IoC 设置的依赖关系

但是,我们现在需要从这个其他控制器调用该方法。
完整的答案是:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);


//Call your method
ActionInvoker.InvokeAction(controller.ControllerContext, "MethodNameFromControllerB_ToCall");

如果有人正在研究如何在。我通过在启动时添加控制器来实现它

services.AddTransient<MyControllerIwantToInject>();

然后把它注入另一个控制器

public class controllerBeingInjectedInto : ControllerBase
{
private readonly MyControllerIwantToInject _myControllerIwantToInject


public controllerBeingInjectedInto(MyControllerIwantToInject myControllerIwantToInject)
{
_myControllerIwantToInject = myControllerIwantToInject;
}

那就像这样叫它 _myControllerIwantToInject.MyMethodINeed();

我知道这很古老,但你可以:

  • 创建一个服务层
  • 移动方法在那里
  • 两个控制器中的调用方法

如果你使用.NET Core 或.NET 5 < 你可以这样做:

MVC:

services.AddMvc().AddControllersAsServices();

返回文章页面

services.AddControllers().AddControllersAsServices();

然后您可以像注入其他服务一样简单地注入控制器