Подтвердить что ты не робот

MVC ViewBag Best Practice

Для ViewBag, я слышал, что это было не-нет. Я предполагаю, что содержимое из ViewBag должно быть включено в модель представления?

Вопрос:

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

  • Есть ли ситуации, когда ViewBag абсолютно необходим?

4b9b3361

Ответ 1

ViewBag - динамический словарь. Поэтому при использовании ViewBag для передачи данных между методами действий и представлениями ваш компилятор не сможет поймать, если вы делаете опечатку в своем коде при попытке получить доступ к элементу ViewBag в своем представлении. Ваше представление будет сбой во время выполнения: (

Как правило, рекомендуется использовать модель представления для передачи данных между вашими методами действий и представлениями. view model - это простой класс POCO, который имеет свойства, специфичные для представления. Поэтому, если вы хотите передать некоторые дополнительные данные для просмотра, добавьте новое свойство в свою модель просмотра и используйте это. Строго введенные представления делают код более чистым и более простым в обслуживании. При таком подходе вам не нужно делать явное литье вашего словаря словаря вида для некоторых типов назад и вперед, которые вы должны делать с сумкой представления.

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 для отправки данных. Например, вы хотите отобразить что-то на странице Layout, для этого вы можете использовать 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>

Ответ 2

1) Является ли мое предположение выше наилучшей практики. (Не использовать ViewBag и второй, чтобы иметь его в модели представления)

Вы должны использовать viewmodels вместо передачи данных через ViewBag как можно больше.

2) Существуют ли ситуации, когда ViewBag абсолютно необходим?

Нет никакой ситуации, когда ViewBag абсолютно необходим. Однако есть некоторые данные, которые я лично предпочитаю использовать ViewBag вместо View Model. Например, когда мне нужно заполнить раскрывающийся список для предопределенных значений (например, Города), я использую ViewBag для переноса массива SelectListItem для просмотра. Я предпочитаю не загрязнять мои ViewModels этими данными.

Ответ 3

1) Является ли мое предположение выше наилучшей практики. (Не использовать ViewBag и второй, чтобы иметь его в модели представления)

Да.

2) Существуют ли ситуации, когда ViewBag абсолютно необходим?

Нет. Все, что вы сохранили в ViewBag, может перейти в модель представления, переданную в представление.

Ответ 4

Проблема с ViewBags и рекомендуемая передовая практика сводятся к компиляции времени. ViewBags - это просто словари, и с этим вы получаете "магические" строки, поэтому, если вы в конечном итоге измените тип объекта одного из элементов представления или имя ключа, которое вы не узнаете до времени выполнения, даже если предварительно прекомпилировать представления с помощью <MvcBuildViews>true</MvcBuildViews>.

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

Ответ 5

Я нашел некоторое использование для ViewBag, где есть общая функциональность на всех страницах, и функциональность не зависит от отображаемой страницы. Например, предположим, что вы создаете StackOverflow. На каждой странице отображается доска задания, но показанные задания не имеют ничего общего с этой страницей (мое использование было похоже на концепцию). Добавление свойства в каждую ViewModel было бы трудным и трудоемким, а также много пуха для ваших тестов. Я не думаю, что это стоит того в этой ситуации.

Я использовал базовый класс ViewModel с данными перекрестной резки, но если у вас несколько (например, заданий и список сайтов обмена стеками), вам нужно либо начать набивать лишние данные, либо какое-либо другое злоупотребление ViewModel, плюс вам понадобится построитель ViewModel для заполнения базовых данных.

Что касается проблемы магических строк, существует множество решений. Константы, методы расширения и т.д.

При всем том, если у вас есть что-то, что отображается на вашей странице, которое зависит от контекста страницы, ViewModel - ваш друг.

Эрик

Ответ 6

Если вы не можете перепроектировать EXISTING ViewModel, используйте ViewBag.

Ответ 7

  • Нет. Используйте ViewModels.
  • Нет. Если вы создаете идеальный ViewModel, вам никогда не понадобится ViewBag.

Ответ 8

2. Существуют ли ситуации, когда ViewBag абсолютно необходим?

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

Ответ 9

Если бы для этого не было вариантов использования, это не было бы реализовано в первую очередь. Да, вы можете делать все с помощью 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>

Но что, если вы хотите выбрать родительскую категорию категории? Объект DTO идеально держит только собственные значения, поэтому для заполнения списка выбора вы используете ViewBag

<select asp-for="ParentId" asp-items="ViewBag.ParentList">
    <option value="">None</option>
</select>

Зачем это делать? Хорошо, если у вас есть 50 типов сущностей, каждый из которых имеет какой-то выбор из разных значений, вы просто избегаете создания 50 дополнительных ViewModels.