Не удается получить доступ к ViewBag в частичном представлении в ASP.NET MVC3 - PullRequest
51 голосов
/ 20 апреля 2011

У меня есть контроллер, вызывающий представление. В представлении есть PartialView с именем be @Html.Partial("ViewName", model).. Это прекрасно работает.

Но в controller я хотел бы поместить что-то в сумку вида, что было бы трудно поместить в модель представления, которую я передаю представлению. Главный экран не имеет проблем с доступом к ViewBag, но в PartialView он ничего не возвращает.

Можно ли в этом случае использовать ViewBag или я должен "взломать" эти данные в модель, которую я передаю в представление (и модель, которую я передаю в PartialView, и модель, которую я передаю в PartialView вложено в первый PartialView)?

Ответы [ 7 ]

45 голосов
/ 21 апреля 2011

Это должно работать без проблем.В своем действии HomeController Index я добавляю сообщение в ViewBag:

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

. В представлении Index я добавляю частичное представление:

@Html.Partial("ViewName")

И в частичном представлении я отображаю сообщение:

@ViewBag.Message

Из комментариев ниже: кажется, что возникает проблема, когда вы передаете модель в частичное представление.Тогда вы можете сослаться на оригинальный ViewBag с

@ViewContext.Controller.ViewBag.Message
31 голосов
/ 17 июня 2013

Если вы используете перегрузку Html.Partial(), где viewData является одним из входных параметров, например:

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

, тогда ваше частичное представление не будет видеть данные из вашего исходного ViewBag.

Удалить new ViewDataDictionary(ViewBag), поэтому вы должны написать

@Html.Partial("PartialViewName", Model)
10 голосов
/ 01 мая 2015

В комментарии TehOne сказано:

Я знаю, что это немного устарело, но для дальнейшего использования я решил эту проблему с помощью ViewContext.Controller.ViewBag.Property.Конечно, это означает, что свойство ViewBag, к которому вы пытаетесь получить доступ, было установлено в контроллере, но я думаю, что это достаточно распространенный случай.

Вот что сработало для меня.

8 голосов
/ 23 мая 2015

Недавно у меня возникла та же проблема, но ответы здесь были просто обходными путями, поскольку они предлагают не использовать перегрузку Html.Partial при использовании viewData. Но если бы вам пришлось использовать эти перегрузки, я считаю, что правильный ответ:

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

Я думаю, что этот ответ следует использовать, если вам нужно передать другой ViewDataDictionary (например, я использую его для изменения HtmlFieldPrefix) и потому что в представлении вы должны знать, какой частичный просмотр понадобится в ViewBag, поэтому не должно быть проблемой назвать все параметры из ViewBag для копирования в новый ViewBag, используемый в частичном представлении (очевидно, ViewBag использует значения из ViewData).

2 голосов
/ 12 апреля 2019

> В общем случае при использовании Html.Partial;

Html.Partial("partialViewName");

Модель, отправляемую для parentView, можно использовать дляpartalViewName.Кроме того, ViewData, который отправляется для parentView, также может использоваться для частичного ViewName.

> В качестве особого случая, когда вы используете Html.Partial и если вы хотите отправить Model..

Html.Partial("partialViewName", newModel);

Вы не можете найти модель, которая была отправлена ​​для parentView.Следовательно, с сегодняшнего дня Модель, которая активна вpartalViewName, является newModel.ViewData, который отправляется для parentView, может использоваться также для частичного ViewName.

> В качестве особого случая, когда вы используете Html.Partial и хотите отправить ViewDataDictionary ..

Модель, отправляемая для parentView, может использоваться также для частичного вида

I.

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

Здесь ViewData, который был отправлен для parentView, перезаписан с помощью 'new ViewDataDictionary'.

Здесь, если есть ViewBag, предназначенный для parentView, вы не сможете достичь этого, если напишите код, подобный приведенному выше.

II.

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

Это использование аналогично первому (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)

С помощью этого кодового блока вы можете получить доступ к ViewData и ViewBag, которые отправляются для parentView вpartalViewName

.
0 голосов
/ 25 октября 2017

У меня была такая же проблема с очень простой страницей:

@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>

И частичное представление содержало только текст с некоторыми ссылками на ViewBag для извлечения некоторых динамических значений, переданных из контроллера. Оказалось, что название частичного представления имело значение. Удаление частичной страницы и воссоздание ее с помощью Add -> View -> MVC 5 View, но присвоение имени странице _AppIntro.cshtml исправило ее.

0 голосов
/ 01 августа 2015

Мой senario был, у меня было частичное представление с моделью IEnumerable<SampleModel> Однако я должен был пройти с помощью, потому что Model.SampleModelList может быть null

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

Простое решение состояло в том, что PartialView теперь также является частью View. Каждый элемент в View может быть доступен через PartialView, поэтому я установил для данных ViewBag элемент данных в View html вместо ViewBag.

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