在不同的控制器上调用.NET MVC方法

任何人都可以告诉我如何从一个操作方法内的不同的控制器上调用一个方法? 我不想redirect。 我想在不同的控制器上调用一个方法,该方法返回一个string,并在我的action方法中使用响应。

听起来像你应该重构你的应用程序,并提取生成string的function,以一个新的单独的类(或重用一个现有的类,如果你有一个合适的),让两个控制器使用该类。

您可以使用以下方法在其他控制器上调用方法:

var otherController = DependencyResolver.Current.GetService<OtherController>(); var result = otherController.SomeMethod(); 

这在ASP.NET MVC5中为我工作。 希望它也能为你工作。

你可以在你的动作方法中实例化控制器并调用你需要的其他方法吗?

 public ActionResult YourActionMethod() { SomeController c = new SomeController(); ActionResult result = c.SomeMethod(); return View(); } 

你可以通过HtmlHelperAction方法来实现。

有鉴于此,你可以这样做:

 @Html.Action("OtherAction") 

然而,在操作方法中(通过devise)获取HtmlHelper的实例并不简单。 其实这是一个非常可怕的黑客,我不愿意发布它…

 var htmlHelper = new HtmlHelper(new ViewContext( ControllerContext, new WebFormView(ControllerContext, "HACK"), new ViewDataDictionary(), new TempDataDictionary(), new StringWriter()), new ViewPage()); var otherViewHtml = htmlHelper.Action("ActionName", "ControllerName"); 

这适用于MVC 3.您可能需要从MVC 2,IIRC的ViewContext构造函数中删除StringWriter arg。

</劈>

我没有使用Castle Windsor IoC,但理论上你应该能够创build一个自定义的Controller工厂类,然后指示MVC框架使用这个自定义控制器工厂,通过在Global.asax.css文件中注册它,在Application_Start事件中:

 protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactor()); } 

[参见Asp.Net MVC 2框架,Steven Sanderson,Apress,第64-66页]

这样,你可以在你的代码中的任何地方实例化你的控制器。

NOT调用另一个控制器从“当前”控制器或其他代码的行为的概念是相当错误的。 控制器只是类。 当MVC框架以特殊的方式调用它们时,它们只会成为“控制器”。

所以,这个对错是归结为什么你这样做,而不是不pipe你是否应该这样做。

如果你只是使用控制器作为一个类,那么这很好。 如果您尝试使用此function向用户发送响应,则应如上所述使用RedirectToAction。

将控制器用作类而不是控制器有许多原因。 例如,testing你的控制器。 因此,把你的控制器作为一个类来处理是必要的,而不是错误的。

使用控制器作为类的非testing场景示例:

我正在编写一个小型框架,利用MVC框架的模板function为HTML电子邮件生成HTML,这是所有Web应用程序出于某种原因(例如订单确认电子邮件)需要执行的操作。

非常粗略地说,在NormalController的操作(需要发送电子邮件)中实例化您的MailManagerController(为了简单起见,假定您没有使用IoC),然后执行:

 MailManagerController mailmanager = new MailManagerController(); string html = mailmanager.OrderConfirmation(order).RenderToString(); Postman.SendEmail(html, order.UserEmailAddress, "MyApp order confirmation"); 

RenderToString是ViewResultBase上的一个扩展方法,它将一个Action(返回一个ViewResultBase对象)的输出呈现给一个string,而Postman是一个静态类,它处理一旦你有文本就发送邮件。

这种技巧的好处是,你可以使用MVC框架来生成模板化的电子邮件,因为OrderConfirmation Action将有一个关联的视图,如果不是你要发送的电子邮件的html模板,那么这个视图就是没有关系的。

看起来你正在试图做一些控制器没有devise的东西。 在某些类中将您所需的方法devise为公共方法,并从两个控制器操作中调用。

我在寻找同样的东西,但认真的人,为什么需要写这么复杂的答案。

这里有一个post会很简单地回答: 使用Html.ActionLink在不同的控制器上调用action

基本上你只需要使用这个actionlink的重载: ActionLink(HtmlHelper, String, String, String, Object, Object)

所以你将有: ActionLink("linkText", "actionName", "controllerName", routeValues, htmlAttributes)

如果您没有任何routeValues(这是Action的input)或htmlAttributes,则必须将它们设置为null。

下面是一个示例调用: @Html.ActionLink("Add New Student", "Create", "Student", null, new { @class = "btn btn-primary" })