Quelqu'un peut-il me dire comment appeler une méthode sur un contrôleur différent à partir d'une méthode d'action ? Je ne veux pas faire de redirection. Je veux appeler une méthode sur un contrôleur différent qui renvoie une chaîne et utiliser la réponse dans ma méthode d'action.
Réponses
Trop de publicités?Vous pouvez y parvenir par le biais de l'option Action
méthode de HtmlHelper
.
Dans une vue, vous le feriez comme ceci :
@Html.Action("OtherAction")
Cependant, il n'est pas simple d'obtenir une instance de HtmlHelper
dans une méthode d'action (à dessein). En fait, c'est un hack tellement horrible que j'hésite à le poster...
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");
Cela fonctionne sur MVC 3. Il se peut que vous deviez supprimer le StringWriter
arg du ViewContext
pour MVC 2, IIRC.
</hack>
Je n'ai pas utilisé l'IoC de Castle Windsor, mais en théorie, vous devriez pouvoir créer une classe de fabrique de contrôleur personnalisée, puis demander au cadre MVC d'utiliser cette fabrique de contrôleur personnalisée, en l'enregistrant dans le fichier Global.asax.css, dans l'événement Application_Start :
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactor());
}
[Voir Pro Asp.Net MVC 2 Framework, Steven Sanderson, Apress, pages 64 - 66].
De cette façon, vous pouvez instancier vos contrôleurs depuis n'importe où dans votre code.
La notion de NE PAS appeler les actions d'un autre contrôleur à partir du contrôleur "actuel" ou d'un autre code est tout à fait erronée. Les contrôleurs ne sont que des classes. Ils ne deviennent des "contrôleurs" que lorsqu'ils sont invoqués d'une manière spéciale par le cadre MVC.
Par conséquent, le bien et le mal se résument à la question de savoir POURQUOI vous faites cela, et non PAS SI vous devriez le faire ou non.
Si vous utilisez simplement un contrôleur comme classe, c'est parfait. Si vous essayez de l'utiliser pour envoyer une réponse à l'utilisateur, alors vous devez utiliser une RedirectToAction comme suggéré ci-dessus.
Il existe un certain nombre de raisons d'utiliser un contrôleur comme une classe plutôt que comme un contrôleur. Par exemple, lorsque vous testez votre contrôleur. Par conséquent, il est nécessaire de traiter vos contrôleurs comme une classe plutôt que comme une erreur.
Un exemple d'utilisation d'un contrôleur comme classe dans un scénario de non-test :
Je suis en train d'écrire un mini framework qui exploite les capacités de modélisation du framework MVC pour produire le HTML des courriels en HTML, ce que toutes les applications web doivent faire, pour une raison ou une autre (par exemple, les courriels de confirmation de commande).
En gros, vous instanciez votre MailManagerController (pour simplifier, supposons que vous n'utilisez pas d'IoC) dans l'action de votre NormalController (qui doit envoyer un courriel), puis vous le faites :
MailManagerController mailmanager = new MailManagerController();
string html = mailmanager.OrderConfirmation(order).RenderToString();
Postman.SendEmail(html, order.UserEmailAddress, "MyApp order confirmation");
Où RenderToString est une méthode d'extension de ViewResultBase qui rend le résultat d'une action (qui renvoie un objet ViewResultBase) en une chaîne de caractères, et Postman est une classe statique qui s'occupe de l'envoi de courriels une fois que vous avez le texte.
La beauté de cette technique est que vous pouvez utiliser le cadre MVC pour produire des courriels modélisés, car l'action OrderConfirmation aura une vue associée qui n'est rien d'autre qu'un modèle html pour le courriel que vous allez envoyer.