有人能告诉我如何在动作方法中调用不同控制器上的方法吗?我不想重定向。我想在不同的控制器上调用一个方法,该控制器返回一个字符串并在我的action方法中使用响应。
答案 0 :(得分:42)
听起来像你应该重构你的应用程序,并将生成字符串的功能提取到一个新的单独类(或重用现有的类,如果你有一个适合)并让两个控制器使用该类。
答案 1 :(得分:22)
您可以使用以下方法在另一个控制器上调用方法:
var otherController = DependencyResolver.Current.GetService<OtherController>();
var result = otherController.SomeMethod();
这在ASP.NET MVC5中对我有用。希望它也适合你。
答案 2 :(得分:12)
你能在动作方法中实例化控制器并调用你需要的其他方法吗?
public ActionResult YourActionMethod()
{
SomeController c = new SomeController();
ActionResult result = c.SomeMethod();
return View();
}
答案 3 :(得分:11)
您可以通过HtmlHelper
的{{3}}方法实现此目的。
在视图中,您可以这样做:
@Html.Action("OtherAction")
然而,在动作方法中(按设计)获取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的StringWriter
构造函数中删除ViewContext
arg。
&LT; /劈&GT;
答案 4 :(得分:9)
我没有使用Castle Windsor IoC,但理论上你应该能够创建一个自定义的Controller工厂类,然后通过在Global.asax中注册它来指示MVC框架使用这个自定义控制器工厂。 .css文件,在Application_Start事件中:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactor());
}
[参见Pro Asp.Net MVC 2框架,Steven Sanderson,Apress,第64-66页]
这样,您可以从代码中的任何位置实例化控制器。
NOT从“当前”控制器或其他代码调用另一个控制器的操作的概念是非常错误的。控制器只是类。它们只有在MVC框架以特殊方式调用时才会成为“控制器”。
因此,这的正确与错误归结为你为什么这样做,而不是你应该与否。
如果您只是将控制器用作类,那么这很好。如果您尝试使用此方法向用户发送响应,则应使用上面建议的RedirectToAction。
将控制器用作类而不是控制器有很多原因。例如,在测试控制器时。因此,将控制器视为一个类是必要的而不是错误。
将Controller用作类的非测试场景示例:
我正在编写一个迷你框架,利用MVC框架的模板功能来生成HTML电子邮件的HTML,这是所有网络应用程序需要做的事情,原因之一(例如,订单确认电子邮件)。
非常粗略地说,您在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对象)呈现给一个字符串,而Postman是一个静态类,它处理一旦你有了文本就发送电子邮件。
这种技术的优点在于你可以使用MVC框架来生成模板化的电子邮件,因为OrderConfirmation Action将有一个关联的视图,如果不是你要发送的电子邮件的html模板,那就什么都不是。
答案 5 :(得分:2)
看起来你正试图做一些控制器不适合的事情。 将所需方法设计为某个类中的公共方法,并从两个控制器操作中调用。
答案 6 :(得分:-6)
我一直在寻找同样的东西,但是认真的人,为什么需要写出如此复杂的答案。
这是一篇非常简单的回答: Using Html.ActionLink to call action on different controller
基本上你只需要使用actionlink的这个重载:
ActionLink(HtmlHelper, String, String, String, Object, Object)
所以你会:
ActionLink("linkText", "actionName", "controllerName", routeValues, htmlAttributes)
如果您没有任何routeValues(Action的输入)或htmlAttributes,则必须将它们设置为null。
以下是一个示例电话:
@Html.ActionLink("Add New Student", "Create", "Student", null, new { @class = "btn btn-primary" })