MVC ViewBag Лучшая практика
для ViewBag, я слышал, что это не-нет, чтобы использовать. Я бы предположил, что контент из ViewBag должен быть включен в модель представления?
вопрос:
мое предположение выше лучшей практики. (Не использовать ViewBag и второй, чтобы иметь его в модели представления)
существуют ли ситуации, когда ViewBag абсолютно необходим?
9 ответов
ViewBag-это динамический словарь. Поэтому при использовании ViewBag для передачи данных между методами действий и представлениями компилятор не сможет поймать, если вы сделаете опечатку в коде при попытке доступа к элементу ViewBag в представлении. Ваш вид будет сбой во время выполнения: (
обычно рекомендуется использовать модель представления для передачи данных между методами действий и представлениями. модель представления-это простой класс POCO, который имеет свойства, характерные для представления. Так что, если хочешь сдать некоторые дополнительные данные для просмотра, добавьте новое свойство в модель представления и используйте его.Строго типизированные представления делают код более чистым и простым в обслуживании. При таком подходе вам не нужно делать явное литье элемента словаря viewbag для некоторых типов назад и вперед, которые вы должны делать с View bag.
public class ProductsForCategoryVm
{
public string CategoryName { set;get; }
public List<ProductVm> Products { set;get;}
}
public class ProductVm
{
public int Id {set;get;}
public string Name { set;get;}
}
и в вашем методе действия создайте объект этой модели представления, загрузите свойства и отправьте их в представление.
public ActionResult Category(int id)
{
var vm= new ProductsForCategoryVm();
vm.CategoryName = "Books";
vm.Products= new List<ProductVm> {
new ProductVm { Id=1, Name="The Pragmatic Programmer" },
new ProductVm { Id=2, Name="Clean Code" }
}
return View(vm);
}
и ваш взгляд, который строго набранная модель представления,
@model ProductsForCategoryVm
<h2>@Model.CategoryName</h2>
@foreach(var item in Model.Products)
{
<p>@item.Name</p>
}
выпадающий данных ?
многие учебники / книги имеют примеры кода, который использует ViewBag для выпадающих данных. Я лично все еще считаю, что ViewBag не должен использоваться для этого. Это должно быть свойство типа List<SelectListItem
> в вашей модели представления для передачи выпадающих данных. Вот это в должности С примером кода о том, как это сделать.
есть ли ситуации, когда ViewBag абсолютно надо?
есть несколько допустимых случаев использования, где вы можете(не надо) используйте ViewBag для отправки данных. Например, вы хотите отобразить что-то на своей странице макета, для этого вы можете использовать ViewBag. Другой пример:ViewBag.Title
(для заголовка страницы) присутствует в шаблоне MVC по умолчанию.
public ActionResult Create()
{
ViewBag.AnnouncementForEditors="Be careful";
return View();
}
и в макете, вы можете прочитать ViewBag.AnnouncementForEditors
<body>
<h1>@ViewBag.AnnouncementForEditors</h1>
<div class="container body-content">
@RenderBody()
</div>
</body>
1) мое предположение выше лучшей практики. (Не использовать ViewBag и во-вторых, чтобы иметь его в виде модели)
вы должны использовать viewmodels вместо передачи данных через ViewBag как можно больше.
2) Существуют ли ситуации, когда ViewBag абсолютно необходим?
нет ситуации, когда ViewBag абсолютно необходим. Однако есть некоторые данные, которые я лично предпочитаю использовать ViewBag вместо модель представления. Например, когда мне нужно заполнить раскрывающийся список для предопределенных значений (i.E города), я использую ViewBag для переноса массива SelectListItem для просмотра. Я предпочитаю не загрязнять мои ViewModels этими данными.
1) мое предположение выше лучшей практики. (Не использовать ViewBag и во-вторых, чтобы иметь его в виде модели)
да.
2) Существуют ли ситуации, когда ViewBag абсолютно необходим?
нет. Все, что вы сохранили в ViewBag, может войти в модель представления, переданную в представление.
проблема с ViewBags и рекомендуемой лучшей практикой сводится к проверке времени компиляции. ViewBags - это просто словари, и с этим вы получаете "волшебные" строки, поэтому, если вы в конечном итоге измените тип объекта одного из элементов viewbag или имя ключа, вы не узнаете до выполнения, даже если вы предварительно скомпилируете представления с помощью <MvcBuildViews>true</MvcBuildViews>
.
лучше всего придерживаться моделей просмотра, даже если вам нужно время от времени изменять их, чтобы соответствовать определенному виду.
Я нашел некоторое использование для ViewBag, где есть общая функциональность на всех страницах, и функциональность не зависит от отображаемой страницы. Например, предположим, вы создаете StackOverflow. На каждой странице отображается доска заданий, но показанные задания не имеют ничего общего со страницей (мое использование было похоже на концепцию). Добавление свойства к каждой ViewModel будет сложным и трудоемким, а много пуха на тесты. Не думаю, что это того стоит. ситуация.
Я использовал базовый класс ViewModel с перекрестными данными, но если вы больше одного (например, задания и список сайтов stack exchange), вам нужно либо начать заполнять дополнительные данные, либо какое-то другое злоупотребление ViewModel, плюс вам нужен ViewModel builder для заполнения базовых данных.
Что касается проблемы волшебных строк, есть много решений. Константы, методы расширения и т. д.
со всем, что сказал, Если у вас есть что-то, что отображается на странице, которая зависит от контекста страницы, ViewModel является вашим другом.
Эрик
- нет. Использовать ViewModels.
- нет. Если вы создаете идеальную ViewModel, вам никогда не понадобится ViewBag.
2.Есть ли ситуации, когда ViewBag абсолютно необходим?
в некоторых случаях вам нужно будет поделиться своими данными с контроллером между макетами, представлениями и частичными представлениями. В этом случае ViewBag очень полезен, и я сомневаюсь, что есть лучший способ.
Если бы для него не было вариантов использования, он не был бы реализован в первую очередь. Да, вы можете делать все с ViewModels, но что, если вам это действительно не нужно? Одним из таких сценариев является редактирование сущностей. Вы можете передать DTO непосредственно в качестве модели.
@model CategoryDto
<div class="md-form form-sm">
<input asp-for="Name" class="form-control">
<label asp-for="Name">("Category Name")</label>
</div>
но что, если вы хотите выбрать категорию родителя? Entity DTO идеально содержит только собственные значения, поэтому для заполнения списка выбора вы используете ViewBag
<select asp-for="ParentId" asp-items="ViewBag.ParentList">
<option value="">None</option>
</select>
почему это? Ну если у вас есть 50 типов сущностей каждого с каким-то выбором из разных значений вы просто избежали создания 50 дополнительных ViewModels.