Comment ViewBag dans ASP.NET MVC travaille dans les coulisses?
je suis à la lecture d'un livre sur ASP.NET MVC et je me demande comment l'exemple suivant fonctionne:
exemple #1
Controller
public class MyController : Controller
{
public ActionResult Index()
{
ViewBag.MyProperty = 5;
return View();
}
}
View
<h1>@ViewBag.MyProperty</h1>
Maintenant, je comprends que ViewBag
est un objet dynamique, donc c'est comme ça que vous pouvez définir la propriété (même si Je ne connais pas grand chose aux objets dynamiques, Je n'ai jamais travaillé avec eux.) Mais comment la vue obtient-elle l'instance spécifique de ViewBag
du contrôleur, même si on ne passe pas rien directement?
je pensais que le ViewBag
peut être public
static
objet, mais ensuite tout changement serait mondial et il ne serait pas spécifiques à une instance de vue.
Pourriez-vous expliquer comment cela fonctionne en arrière-plan?
exemple #2
Controller
public class MyController : Controller
{
public ActionResult Index()
{
ViewBag.MyProperty = 5;
return View();
}
public ActionResult Index2()
{
ViewBag.MyProperty = 6;
return View();
}
}
maintenant, disons le Index
la méthode s'appelle d'abord, puis la Index2
. En fin de compte la valeur de ViewBag.MyProperty
finira 6 (la valeur à partir 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 ça n'a pas d'importance ASP.NET MVC, comme le web est apatride. Est-ce le cas?
3 réponses
ViewBag
est un ControllerBase
, dont tous les contrôleurs doivent hériter. C'est un dynamic
object, c'est pourquoi vous pouvez y ajouter de nouvelles propriétés sans avoir d'erreurs de compilation.
Ce n'est pas static
, c'est un membre de l'objet. Pendant la durée de vie de la requête, l'instance du contrôleur est créée et éliminée, de sorte que vous n'aurez pas de problèmes de "simultanéité", comme l'écrasement de la valeur.
View
(et ses variantes) méthode n'est pas static
en tant que bien, et c'est comment la vue reçoit l' ViewBag
valeurs: pendant le processus de rendu de la vue, l'instance du contrôleur a son ViewBag.
Si vous souhaitez analyser ControllerBase classe vous verriez que la propriété ViewBag est un "proxy" pour la propriété ViewData juste pour rendre votre source plus jolie. (Je me souviens même de Scott Hanselman prenant interview de Phil Haack où Phil introduit la propriété ViewBag comme un raccourci vers ViewData et l'élimination de la nécessité de crochets répétés et des citations). Même si ViewBag
la propriété est exposée comme dynamic
objet qu'il met en œuvre un DynamicViewDataDictionary classe qui fonctionne directement avec ViewData.
en regardant le code source de Controller catégorie, vous pouvez trouver cette méthode:
protected internal virtual ViewResult View(string viewName, string masterName, object model)
donc en gros quand vous appelez return View();
à partir de votre controller il crée une nouvelle instance de ActionResult
classe passant ViewData du contrôleur à son constructeur. Exemple ActionResult
est ensuite transmis à un moteur de vue particulier (ASPX, Razor) afin qu'il puisse être utilisé pour rendre une vue en question.
Création De ViewBag / ViewData les parasites publics peuvent être nuisibles. Chaque requête web à votre application MVC crée une nouvelle instance de controller. Si vous avez ViewData/ViewBag comme public statique, alors deux utilisateurs concurrents partageraient les mêmes données à partir de ViewBag / ViewData.
Ici est une vidéo. Discussion on ViewBag (formder ViewModel) commence à 04: 05
ViewBag
est un 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 objet ExpandoObject; vous pouvez y ajouter des propriétés à l'exécution. Sa durée de vie est la même que celle du controller, qui est la durée de vie de la requête HTTP.