2013-01-07 6 views
3

J'ai deux contrôleurs:Quelle est la meilleure approche pour partager des données entre les contrôleurs dans ASP .NET MVC?

public class AController : Controller 
{ 
     public ActionResult AControllerAction() 
     { 
      if (// BControllerAction reported an error somehow) 
      { 
       ModelState.AddModelError("error-key", "error-value"); 
      } 
      ... 
     } 
} 

public class BController : Controller 
{ 
     public ActionResult BControllerAction() 
     { 
      try{Something();} 
      catch(SomethingExceprion) 
      { 
       // here I need to add error info data, 
       // pass it to AController and redirect to 
       // AControllerAction where this error will be added 
       // to model state 
      } 
     } 
} 

Je pense que je peux faire quelque chose comme:

public ActionResult BControllerAction() 
{ 
    try{Something();} 
    catch(SomethingException) 
    { 
     var controller = new AController(); 
     controller.ModelState.AddModelError("error-key", "error-value"); 
     controller.AControllerAction(); 
    } 
} 

Mais je suggère qu'il sera approche révolutionnaire architecture, et je ne veux pas faire comme ça. Y a-t-il un moyen plus simple et plus sûr, sauf de passer l'objet du modèle?

+0

vous utilisez ModelState pour ouvrir une session des exceptions? –

+0

@ Forty-Two, exception sera enregistrée dans le bloc 'catch (SomethingException)' par logger (j'ai simplifié ces détails pour me concentrer sur le problème principal qui m'intéresse), j'ai juste besoin d'informer l'utilisateur de cette erreur par l'action d'un autre contrôleur . – Dmytro

+0

Votre approche est correcte. Vous pouvez exécuter un autre contrôleur et renvoyer son ActionResult. Voir [ici] (http://stackoverflow.com/questions/409049/net-mvc-call-a-controller-action-from-another-controller-action) – semao

Répondre

2

Vous pouvez renvoyer une redirection vers AControllerAction. Vous pouvez utiliser le dictionnaire TempData (similaire à ViewData) pour partager des données à travers un tel appel (les données stockées de cette manière persisteront à la prochaine requête dans la même session, comme expliqué in this blog post).

Exemple:

public class AController : Controller 
{ 
     public ActionResult AControllerAction() 
     { 
      if (TempData["BError"] != null) 
      { 
       ModelState.AddModelError("error-key", "error-value"); 
      } 
      ... 
     } 
} 

public class BController : Controller 
{ 
     public ActionResult BControllerAction() 
     { 
      try{Something();} 
      catch(SomethingExceprion) 
      { 
       TempData["BError"] = true; 
       return RedircetToAction("AControllerAction", "AController"); 
      } 
     } 
} 
+0

TempData est la propriété de la classe 'ControllerBase', donc je ne peux transmettre des données de cette façon qu'entre les actions du même contrôleur mais pas entre plusieurs contrôleurs. – Dmytro

+0

@DmytroTsiniavsky Juste vérifié un de mes projets récents. Il ne semble pas y avoir de problème à l'utiliser entre les contrôleurs. – yoozer8

+0

Bien que je dois admettre, j'aime (et j'ai utilisé) la [solution proposée par Forty-Two] (http://stackoverflow.com/a/14199707/866022). – yoozer8

3

Selon ce que les détails de l'exception que vous devez passer en arrière au contrôleur A, je ferais quelque chose le long des lignes de

public ActionResult BControllerAction() 
{ 
    try{Something();} 
    catch(SomethingException ex) 
    { 
     return RedirectToAction("AControllerAction", "AController", new { errorMessage = ex.Message() }) 
    } 
} 

Et puis changer la signature de la méthode appelée à

public ActionResult AControllerAction(string errorMessage) 
     { 
      if (!String.IsNullOrEmpty(errorMessage)) 
      { 
       //do something with the message 
      } 
      ... 
     } 
Questions connexes