web-dev-qa-db-fra.com

Passage de données entre différentes méthodes d'action du contrôleur

J'utilise ASP.NET MVC 4. J'essaie de transmettre des données d'un contrôleur à un autre contrôleur. Je ne comprends pas bien. Je ne sais pas si c'est possible?

Voici ma méthode d'action source à partir de laquelle je souhaite transmettre les données:

public class ServerController : Controller
{
     [HttpPost]
     public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel)
     {
          XDocument updatedResultsDocument = myService.UpdateApplicationPools();

          // Redirect to ApplicationPool controller and pass
          // updatedResultsDocument to be used in UpdateConfirmation action method
     }
}

Je dois le transmettre à cette méthode d'action dans ce contrôleur:

public class ApplicationPoolController : Controller
{
     public ActionResult UpdateConfirmation(XDocument xDocument)
     {
          // Will add implementation code

          return View();
     }
}

J'ai essayé ce qui suit dans la méthode d'action ApplicationPoolsUpdate mais cela ne fonctionne pas:

return RedirectToAction("UpdateConfirmation", "ApplicationPool", new { xDocument = updatedResultsDocument });

return RedirectToAction("UpdateConfirmation", new { controller = "ApplicationPool", xDocument = updatedResultsDocument });

Comment pourrais-je y parvenir?

69
Brendan Vogt

HTTP et redirections

Récapitulons d’abord le fonctionnement d’ASP.NET MVC:

  1. Lorsqu'une requête HTTP arrive, elle est comparée à un ensemble de routes. Si une route correspond à la demande, l'action du contrôleur correspondant à la route sera invoquée.
  2. Avant d'appeler la méthode d'action, ASP.NET MVC effectue la liaison de modèle. La liaison de modèle est le processus de mappage du contenu de la requête HTTP, qui est en principe juste du texte, avec les arguments fortement typés de votre méthode d'action.

Rappelons-nous également ce qu'est une redirection:

Une redirection HTTP est une réponse que le serveur Web peut envoyer au client, lui demandant de rechercher le contenu demandé sous une autre URL. La nouvelle URL est contenue dans un en-tête Location que le serveur Web renvoie au client. Dans ASP.NET MVC, vous effectuez une redirection HTTP en renvoyant un RedirectResult à partir d'une action.

Passing data

Si vous ne faites que transmettre des valeurs simples telles que des chaînes et/ou des entiers, vous pouvez les transmettre en tant que paramètres de requête dans l'URL de l'en-tête Location. C'est ce qui arriverait si vous utilisiez quelque chose comme

return RedirectToAction("ActionName", "Controller", new { arg = updatedResultsDocument });

comme d'autres l'ont suggéré

La raison pour laquelle cela ne fonctionnera pas, c'est que la XDocument est un objet potentiellement très complexe. Il n’existe aucun moyen simple pour le framework ASP.NET MVC de sérialiser le document en un élément pouvant tenir dans une URL, puis une liaison de modèle à partir de la valeur de l’URL vers votre paramètre d’action XDocument.

En général, transmettre le document au client afin que celui-ci le renvoie au serveur lors de la requête suivante est une procédure très fragile: elle nécessiterait toutes sortes de sérialisation et de désérialisation et toutes sortes de problèmes pourraient se produire. Si le document est volumineux, vous risquez également de perdre beaucoup de bande passante et de nuire gravement aux performances de votre application.

Au lieu de cela, vous souhaitez conserver le document sur le serveur et renvoyer un identifiant au client. Le client transmet ensuite l'identifiant avec la requête suivante et le serveur récupère le document en utilisant cet identifiant.

Stocker des données pour les récupérer à la prochaine requête

La question est donc de savoir où le serveur stocke le document entre-temps. Eh bien, c’est à vous de décider et le meilleur choix dépendra de votre scénario. Si ce document doit être disponible à long terme, vous souhaiterez peut-être le stocker sur un disque ou dans une base de données. S'il ne contient que des informations transitoires, conservez-les dans la mémoire du serveur Web, dans le cache ASP.NET ou dans la variable Session (ou TempData, qui est plus ou moins identique à la variable Session dans. la fin) peut être la bonne solution. Quoi qu'il en soit, vous stockez le document sous une clé qui vous permettra de récupérer le document ultérieurement:

int documentId = _myDocumentRepository.Save(updatedResultsDocument);

et puis vous retournez cette clé au client:

return RedirectToAction("UpdateConfirmation", "ApplicationPoolController ", new { id = documentId });

Lorsque vous souhaitez récupérer le document, vous le récupérez simplement en fonction de la clé:

 public ActionResult UpdateConfirmation(int id)
 {
      XDocument doc = _myDocumentRepository.GetById(id);

      ConfirmationModel model = new ConfirmationModel(doc);

      return View(model);
 }
66
Rune

Avez-vous essayé d'utiliser ASP.NET MVC TempData ?

Le dictionnaire ASP.NET MVC TempData permet de partager des données entre les actions du contrôleur. La valeur de TempData persiste jusqu’à sa lecture ou jusqu’à expiration de la session de l’utilisateur actuel. La persistance des données dans TempData est utile dans des scénarios tels que la redirection, lorsque des valeurs sont nécessaires au-delà d'une requête unique.

Le code ressemblerait à ceci:

[HttpPost]
public ActionResult ApplicationPoolsUpdate(ServiceViewModel viewModel)
{
    XDocument updatedResultsDocument = myService.UpdateApplicationPools();
    TempData["doc"] = updatedResultsDocument;
    return RedirectToAction("UpdateConfirmation");
}

Et dans le ApplicationPoolController:

public ActionResult UpdateConfirmation()
{
    if (TempData["doc"] != null)
    {
        XDocument updatedResultsDocument = (XDocument) TempData["doc"];
            ...
        return View();
    }
}
60
user1073075

Personnellement, je n'aime pas utiliser TempData, mais je préfère transmettre un objet fortement typé comme expliqué dans Passing Information Between Controllers in ASP). .Net-MVC .

Vous devriez toujours trouver un moyen de le rendre explicite et attendu.

11
L-Four

je préfère utiliser ceci au lieu de TempData

public class Home1Controller : Controller 
{
    [HttpPost]
    public ActionResult CheckBox(string date)
    {
        return RedirectToAction("ActionName", "Home2", new { Date =date });
    }
}

et un autre controller Action est

public class Home2Controller : Controller 
{
    [HttpPost]
    Public ActionResult ActionName(string Date)
    {
       // do whatever with Date
       return View();
    }
}

il est trop tard, mais j'espère pouvoir aider à l'avenir

2
Amgad Mohamed