Can anybody tell me how to call a method on a different controller from within an action method? I don't want to redirect. I want to call a method on a different controller that returns a string and use the response within my action method.
Could you just instantiate the controller in your action method and call the other method you need?
public ActionResult YourActionMethod()
{
SomeController c = new SomeController();
ActionResult result = c.SomeMethod();
return View();
}
Looks like you're trying to do something the controllers aren't designed for. Design your required method as an public method in some class and invoke from both controller actions.
Sounds in my ears like you should refactor your application, and extract the functionality that generates the string out to a new seperate class (or reuse an existing class, if you have one that fits) and let both controllers use that class.
I haven't used Castle Windsor IoC, but the theory is that you should be able to create a custom Controller factory class, and then instruct the MVC framework to use this custom controller factory, by registering it in the Global.asax.css file, in the Application_Start event:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactor());
}
[See Pro Asp.Net MVC 2 Framework, Steven Sanderson, Apress, pages 64 - 66]
That way, you can instantiate your controllers from anywhere in your code.
The notion of NOT calling the actions of another controller from the "current" controller, or from other code is quite wrong. Controllers are just classes. They only become "Controllers" when invoked in a special way by the MVC Framework.
Therefore, the right and wrong of this boils down to WHY are you doing this, not WHETHER you should or not.
If you are just using a controller as a class, then this is fine. If you are trying to use this to send a response to the user, then you should use a RedirectToAction as suggested above.
There are a number of reasons to use a controller as a class rather than as a Controller. For example, when testing your controller. Therefore, treating your controllers from as a class is necessary as opposed to wrong.
A non testing scenario example of using a Controller as a Class:
I am writing a mini framework that leverages the MVC framework's templating capabilities to produce the HTML for HTML emails, something that all web apps need to do, for one reason or another (eg, order confirmation emails).
Very roughly, you instantiate your MailManagerController (for simplicity, presume you are not using IoC) in your NormalController's action (that needs to send an email) and then do:
MailManagerController mailmanager = new MailManagerController();
string html = mailmanager.OrderConfirmation(order).RenderToString();
Postman.SendEmail(html, order.UserEmailAddress, "MyApp order confirmation");
Where RenderToString is an extension method on ViewResultBase that renders the output of an Action (that returns a ViewResultBase object) to a string, and Postman is a static class that deals with sending emails once you have the text.
The beauty of this technique is that you can use the MVC framework to produce templated emails, because the OrderConfirmation Action will have an associated view which is nothing if not an html template for your the email you are going to send.