Je lis un livre sur ASP.NET MVC et je me demande comment fonctionne l’exemple suivant:
public class MyController : Controller { public ActionResult Index() { ViewBag.MyProperty = 5; return View(); } }
@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?
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.