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 publicstatic 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?

30
demandé sur Shog9 2013-06-06 00:40:25

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.

27
répondu Andre Calil 2013-06-05 21:53:47

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

10
répondu Ramunas 2013-06-05 21:50:33

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.

6
répondu Robert Harvey 2013-06-06 01:35:57