web-dev-qa-db-fra.com

Impossible d'accéder à ViewBag dans une vue partielle dans ASP.NET MVC3

J'ai un contrôleur qui appelle une vue. Dans la vue, il existe une PartialView appelée soit @Html.Partial("ViewName", model).. Cela fonctionne bien.

Mais dans la controller je souhaite mettre quelque chose dans la vue ce qui serait difficile à mettre dans le modèle de vue que je passe à la vue . La vue principale n'a aucun problème à accéder à la ViewBag, mais dans le PartialView elle ne renvoie rien.

Est-il possible d'utiliser la variable ViewBag dans ce cas ou dois-je "pirater" ces données dans le modèle que je passe à la vue (et le modèle que je passe à la variable PartialView, et le modèle que je transmets à la variable PartialView imbriquée dans la première variable PartialView ?

50
SoonDead

Cela devrait fonctionner sans aucun problème. Dans mon action Index HomeController, j'ajoute un message au ViewBag:

ViewBag.Message = "Welcome to ASP.NET MVC!";

Sur la vue d'index, j'ajoute la vue partielle:

@Html.Partial("ViewName")

Et sur la vue partielle je rend le message:

@ViewBag.Message

D'après les commentaires ci-dessous: il semble y avoir un problème lorsque vous passez un modèle à la vue partielle. Ensuite, vous pouvez vous référer au ViewBag original avec

@ViewContext.Controller.ViewBag.Message
43
slfan

Si vous utilisez une surcharge de Html.Partial()viewData est l'un des paramètres d'entrée, par exemple:

@Html.Partial("PartialViewName", Model, new ViewDataDictionary(ViewBag))

alors votre vue partielle ne verra pas les données de votre ViewBag d'origine.

Supprimer new ViewDataDictionary(ViewBag), vous devriez donc écrire

@Html.Partial("PartialViewName", Model)
30
Andzej Maciusovic

Dans un commentaire TehOne a déclaré:

Je sais que c'est un peu vieux, mais pour référence future, j'ai résolu ceci par en utilisant ViewContext.Controller.ViewBag.Property. Bien sûr, cela signifie que la propriété ViewBag à laquelle vous essayez d'accéder a été définie dans le fichier contrôleur, mais je pense que c'est un cas assez commun.

C'est ce qui a fonctionné pour moi.

9
jmoreno

Récemment, j’ai rencontré le même problème, mais les réponses ici ne sont que des solutions de contournement car ils proposent de ne pas utiliser la surcharge de Html.Partial en utilisant viewData. Mais si vous deviez utiliser ces surcharges, je pense que la bonne réponse est:

@Html.Partial(
     "PartialViewName",
     model_object,
     new ViewDataDictionary() { { "Value1InViewBag", ViewBag.Value1InViewBag }, { "Value2InViewBag", ViewBag.Value2InViewBag } }
)

Je pense que cette réponse devrait être utilisée si vous devez transmettre ViewDataDictionary différent (par exemple, je l’utilise pour changer HtmlFieldPrefix) et parce que, de l’avis, vous devez savoir quelle vue partielle sera nécessaire dans ViewBag, il ne devrait donc pas être difficile de nommer tous les les paramètres de ViewBag à copier dans la nouvelle ViewBag utilisée dans la vue partielle (apparemment ViewBag utilise les valeurs de ViewData).

7
Zoka

> Dans un scénario général, lorsque vous utilisez Html.Partial;

Html.Partial("partialViewName");

Le modèle envoyé pour parentView peut être utilisé dans partialPartName. De plus, le ViewData envoyé pour parentView peut également être utilisé pour partialViewName.

> Comme cas particulier, lorsque vous utilisez Html.Partial et si vous souhaitez envoyer un modèle ..

Html.Partial("partialViewName", newModel);

Vous ne pouvez pas atteindre le modèle qui a été envoyé pour parentView. Par conséquent, à partir de maintenant, le modèle actif dans le partialViewName est le newModel. Le viewData envoyé pour parentView peut être utilisé également pour partialViewName.

> Comme cas particulier, lorsque vous utilisez Html.Partial et si vous souhaitez envoyer ViewDataDictionary ..

Le modèle envoyé pour parentView peut également être utilisé pour partialViewName

I.

@Html.Partial("partialViewName", new ViewDataDictionary { { "key", value }, { "key2", value2 }  })

Ici, les ViewData envoyées pour parentView sont écrasées par 'new ViewDataDictionary'.

Ici, s'il existe un ViewBag destiné à parentView, vous ne pourrez pas l'atteindre si vous écrivez le code comme ci-dessus.

II.

ViewDataDictionary viewDataDictionary =  new ViewDataDictionary();
viewDataDictionary.Add("key", value);
viewDataDictionary.Add("key2", value2);
@Html.Partial("partialViewName", viewDataDictionary)

Cet usage est identique au premier (I.).

III.

ViewDataDictionary viewDataDictionary = ViewData; //If you use this code block,  ViewBag which is sent for parent View is not lost.
viewDataDictionary.Add("key", value);
viewDataDictionary.Add("key2", value2);
@Html.Partial("partialViewName", viewDataDictionary)

Avec ce bloc de code, vous pouvez accéder aux ViewData et ViewBag qui sont envoyés pour parentView dans le partialViewName.

2
Erkan Kamazoğlu

J'avais ce même problème avec une page très basique:

@Html.Partial("_AppIntro")

<div class="form-group row">
    <div class="col-md-10">
        <a href="/Ag/Application/1" class="btn btn-default btn-primary">Next</a>
    </div>
</div>

Et la vue partielle ne contenait que du texte avec quelques références à ViewBag pour extraire certaines valeurs dynamiques transmises par le contrôleur. Il s'est avéré que le nom de la vue partielle importait. Supprimer la page partielle et la recréer avec Add -> View -> MVC 5 View mais en nommant la page _AppIntro.cshtml a résolu le problème.

0
John Sully

Mon senario était, j'avais vue partielle avec le modèle IEnumerable<SampleModel> Cependant, je devais passer à l'aide de coz Model.SampleModelList peut être null

@Html.Partial("PartialViewName", Model.SampleModelList, new ViewDataDictionary())

La solution simple était que, puisque PartialView fait également partie de View, chaque élément de View peut être consulté par PartialView;.

<div class="showcase-heading" id="dvValue" data-id="@Model.ContentId">@Model.Name</div>
0
brykneval