Comment ViewBag dans ASP.NET MVC fonctionne-t-il en coulisse?

Je lis un livre sur ASP.NET MVC et je me demande comment fonctionne l’exemple suivant:

Exemple 1

Manette

public class MyController : Controller { public ActionResult Index() { ViewBag.MyProperty = 5; return View(); } } 

Vue

 

@ViewBag.MyProperty

Maintenant, je comprends que ViewBag est un object dynamic. C’est ainsi que vous pouvez définir la propriété (même si je ne connais pas grand chose aux objects dynamics, je n’ai jamais travaillé avec eux.) Mais comment la vue obtient-elle l’instance spécifique du ViewBag partir du contrôleur, même si nous ne passons rien directement?

Je pensais que le ViewBag pourrait être un object static public , mais toute modification apscope à celui-ci serait globale et ne serait pas spécifique à une instance de vue.

Pourriez-vous préciser comment cela fonctionne dans les coulisses?

Exemple n ° 2

Manette

 public class MyController : Controller { public ActionResult Index() { ViewBag.MyProperty = 5; return View(); } public ActionResult Index2() { ViewBag.MyProperty = 6; return View(); } } 

Index2 maintenant que la méthode Index soit appelée en premier, puis Index2 . En fin de compte, la valeur de ViewBag.MyProperty se termine par 6 (valeur de Index2 ). Je pense que ce n’est pas une bonne chose à faire, mais en même temps, je pense que je pense en termes de développement de bureau. Peut-être que cela n’a pas d’importance lorsqu’il est utilisé avec ASP.NET MVC, car le Web est sans état. Est-ce le cas?

ViewBag est une propriété de ControllerBase , dont tous les contrôleurs doivent hériter. C’est un object dynamic , c’est pourquoi vous pouvez y append de nouvelles propriétés sans générer d’erreurs de compilation.

Ce n’est pas static , c’est un membre de l’object. Pendant la durée de vie de la demande, l’instance de contrôleur est créée et supprimée, vous évitant ainsi des problèmes de “simultanéité”, tels que le remplacement de la valeur.

La méthode View (et ses variantes) n’est pas static non plus, et c’est ainsi que la vue reçoit les valeurs ViewBag : lors du processus de rendu de la vue, l’instance du contrôleur possède également son instance ViewBag.

Si vous parsingz la classe ControllerBase , vous constaterez que la propriété ViewBag est un “proxy” de la propriété ViewData uniquement pour rendre votre source plus belle. (Je me souviens même que Scott Hanselman avait interviewé Phil Haack dans une interview où Phil avait présenté la propriété ViewBag comme raccourci vers ViewData et éliminait ainsi le besoin de crochets et de guillemets répétés). Bien que la propriété ViewBag soit exposée en tant qu’object dynamic , elle implémente une classe DynamicViewDataDictionary qui fonctionne directement avec ViewData.

En regardant le code source de la classe Controller , vous pouvez trouver cette méthode:

 protected internal virtual ViewResult View(ssortingng viewName, ssortingng masterName, object model) 

Donc, fondamentalement, lorsque vous appelez return View(); à partir de votre contrôleur, il crée une nouvelle instance de la classe ActionResult en transmettant ViewData du contrôleur à son constructeur. L’instance d’ ActionResult est ensuite transmise à un moteur de vue particulier (ASPX, Razor) afin qu’elle puisse être utilisée pour restituer une vue en question.

Rendre statique statique ViewBag / ViewData pourrait être dangereux. Chaque requête Web adressée à votre application MVC crée une nouvelle instance de contrôleur. Si vous voulez que ViewData / ViewBag soit public statique, deux utilisateurs simultanés partageront les mêmes données à partir de ViewBag / ViewData.

Voici une vidéo. La discussion sur ViewBag (formder ViewModel) commence à 04:05.

ViewBag est une propriété de ControllerBase . Il est défini comme suit:

 public Object ViewBag { get; } 

Notez que cette signature est en fait incorrecte. Voici à quoi ressemble le code source:

 public dynamic ViewBag { get { if (_dynamicViewDataDictionary == null) { _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData); } return _dynamicViewDataDictionary; } } 

_dynamicViewDataDictionary est un ExpandoObject; vous pouvez y append des propriétés au moment de l’exécution. Sa durée de vie est la même que celle du contrôleur, c’est-à-dire la durée de vie de la requête HTTP.