web-dev-qa-db-fra.com

Comment appeler un autre contrôleur Action Depuis un contrôleur de MVC

J'ai besoin d'appeler une action du contrôleur B FileUploadMsgView depuis le contrôleur A et de lui transmettre un paramètre.

 Code---its not going to the controller B's FileUploadMsgView().
    In ControllerA
  private void Test()
    {

        try
        {//some codes here
            ViewBag.FileUploadMsg = "File uploaded successfully.";
            ViewBag.FileUploadFlag = "2";

            RedirectToAction("B", "FileUploadMsgView", new { FileUploadMsg = "File   uploaded successfully" });
        }

     In ControllerB receiving part
  public ActionResult FileUploadMsgView(string FileUploadMsg)
    {
         return View();
    }
117
user2156088

Les contrôleurs ne sont que des classes - une nouvelle et appellent la méthode d'action comme n'importe quel autre membre de la classe:

var result = new ControllerB().FileUploadMsgView("some string");

97
Tieson T.

Comme @mxmissile indique dans les commentaires de la réponse acceptée, vous ne devriez pas créer de contrôleur, car les dépendances manquantes seront configurées pour IoC et n'auront pas la variable HttpContext.

Au lieu de cela, vous devriez obtenir une instance de votre contrôleur comme ceci:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);
147
DLeh

Votre exemple ressemble à du code pseudo. Vous devez retourner le résultat de RedirectToAction:

return RedirectToAction("B", 
                        "FileUploadMsgView",
                        new { FileUploadMsg = "File uploaded successfully" });
56
Ed Chapel

comme @DLeh dit Utilisez plutôt

var controller = DependencyResolver.Current.GetService<ControllerB>();

Cependant, il est important de donner au contrôleur un contexte de contrôleur, en particulier lorsque vous devez accéder à l'objet User, à l'objet Server ou à la variable HttpContext du contrôleur 'enfant'.

J'ai ajouté une ligne de code:

controller.ControllerContext = new ControllerContext(Request.RequestContext, controller);

ou bien vous auriez pu utiliser System.Web pour accéder également au contexte actuel, pour accéder à Server ou aux objets de type ancien 

NB: je vise la version 4.6 du framework (Mvc5)

13
Nishanth Shaan

Laissez le résolveur le faire automatiquement.

À l'intérieur d'un contrôleur:

public class AController : ApiController
{
    private readonly BController _bController;

    public AController(
    BController bController)
    {
        _bController = bController;
    }

    public httpMethod{
    var result =  _bController.OtherMethodBController(parameters);
    ....
    }

}
6
David Castro

La réponse de Dleh est correcte et explique comment obtenir une instance d'un autre contrôleur sans les dépendances manquantes configurées pour IoC

Cependant, nous devons maintenant appeler la méthode depuis cet autre contrôleur.
La réponse complète serait:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, controller);

//Call your method
ActionInvoker.InvokeAction(controller.ControllerContext, "MethodNameFromControllerB_ToCall");
2
AlexB

C’est exactement ce que je recherchais après avoir découvert que RedirectToAction() ne transmettrait pas les objets de classe complexes. 

Par exemple, je souhaite appeler la méthode IndexComparison dans le contrôleur LifeCycleEffectsResults et lui transmettre un objet de classe complexe nommé modèle.

Voici le code qui a échoué:

return RedirectToAction("IndexComparison", "LifeCycleEffectsResults", model);

Il est à noter que les chaînes, les entiers, etc. ont survécu au passage à cette méthode de contrôleur, mais que les objets de liste génériques souffrent de ce qui rappelle les fuites de mémoire C.

Comme recommandé ci-dessus, voici le code par lequel je l'ai remplacé:

var controller = DependencyResolver.Current.GetService<LifeCycleEffectsResultsController>();

var result = controller.IndexComparison(model);
return result;

Tout fonctionne comme prévu maintenant. Merci d'avoir ouvert la voie.

1
cghore

Si quelqu'un cherche comment faire cela dans le noyau .net, je l'ai accompli en ajoutant le contrôleur au démarrage 

services.AddTransient<MyControllerIwantToInject>();

Puis l'injecter dans l'autre contrôleur 

public class controllerBeingInjectedInto : ControllerBase
{
    private readonly MyControllerIwantToInject _myControllerIwantToInject

     public controllerBeingInjectedInto(MyControllerIwantToInject myControllerIwantToInject)
{
       _myControllerIwantToInject = myControllerIwantToInject;
      }

Ensuite, appelez-le comme si _myControllerIwantToInject.MyMethodINeed();

0
Leonardo Trimarchi

si le problème est d'appeler. vous pouvez l'appeler en utilisant cette méthode. 

yourController obj= new yourController();

obj.yourAction();
0
user5407401