当前位置:  开发笔记 > 后端 > 正文

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

如何解决《不同控制器上的.NETMVC调用方法》经验,为你挑选了5个好方法。

任何人都可以告诉我如何在动作方法中调用不同控制器上的方法吗?我不想重定向.我想在不同的控制器上调用一个方法,该控制器返回一个字符串并在我的action方法中使用响应.



1> Pete..:

听起来像你应该重构你的应用程序,并将生成字符串的功能提取到一个新的单独的类(或重用现有的类,如果你有一个适合)并让两个控制器使用该类.


也许他想要生成的字符串是一个HTML字符串,它已经由不同的控制器构建.考虑将此字符串提供给HTML到PDF生成器的示例.调用控制器动作并在字符串中捕获视图结果听起来像是一个很好的方法.

2> 小智..:

您可以使用以下方法在另一个控制器上调用方法:

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

这在ASP.NET MVC5中对我有用.希望它也适合你.


问题在于,没有上下文。因此,如果您正在使用,例如说“ Server.MapPath(....”),它将出错,因为Server一无所获。

3> Nick..:

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

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

   return View();
}


这个解决方案可以*工作*,但它不够优雅.

4> Drew Noakes..:

你可以通过以下Action方法实现这一目标HtmlHelper.

在视图中,您可以这样做:

@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.您可能需要StringWriterViewContextMVC 2,IIRC 的构造函数中删除arg .



5> awrigley..:

我没有使用Castle Windsor IoC,但理论上你应该能够创建一个自定义的Controller工厂类,然后通过在Global.asax.css文件中注册它来指示MVC框架使用这个自定义控制器工厂,在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,这是所有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对象)呈现给一个字符串,而Postman是一个静态类,它处理一旦你有了文本就发送电子邮件.

这种技术的优点在于您可以使用MVC框架来生成模板化电子邮件,因为OrderConfirmation Action将具有关联的视图,如果不是您要发送的电子邮件的html模板,则该视图是什么.


"因此,这的正确与错误归结为你为什么这样做,而不是你应该与否." 人们可能会争论得非常不同.通常的功能通常可以并且应该重构为服务层.(http://martinfowler.com/eaaCatalog/serviceLayer.html)这个逻辑分区可以在很多地方看到,包括Grails MVC技术堆栈(参见优秀的书,Grails in Action)(http://www.grails.org /doc/1.0.x/guide/8.%20The%20Service%20Layer.html)和SharpArchitecture .NET堆栈(http://wiki.sharparchitecture.net/SettingUpNorthwind.ashx)
推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有