ViewBag против модели в MVC.NET

Это скорее общий архитектурный вопрос:

Я пытаюсь решить, могут ли мои программисты использовать «ViewBags» для передачи данных в представления, которые уже принимают модели.

Лично я предпочитаю избегать ViewBags и создавать надежные модели, содержащие все данные, необходимые для представления:

Подход 1:

MODEL A: 
- List of Employees
- Nullable integer, indicating which item from the list is currently selected
- string firstName (empty if index is null)
- string lastname (empty if index is null)

Подход 2:

MODEL A: 
- List of Employees

ViewBag:
- ViewBag.Index (indicating which item from the list is currently selected)
- ViewBag.FirstName
- ViewBag.LastName

Кто-нибудь может придумать аргумент, почему подход 2 лучше, чем подход 1?

спасибо за ваш вклад


person DotNet98    schedule 12.02.2014    source источник


Ответы (5)


На мой взгляд, вам следует никогда использовать ViewBag без очень, очень веской причины. Ответ Брэда Томаса указывает на редкий пример одной из таких веских причин.

Скажем, у вас есть мастер-макет (или частичное представление), совместно используемое всем веб-сайтом и десятками строго типизированных представлений, каждое из которых имеет собственное Модель. Как вы передаете данные в макет? Некоторые стратегии, которые я видел:

  1. Добавьте свойства макета к каждой модели.

Если у вас не так много моделей или есть только одно или два дополнительных свойства, это может сработать. Это может быстро превратиться в кошмар обслуживания.

  1. Наследуйте все свои модели от класса, содержащего данные макета.

Я избегаю создания класса ModelBase, но иногда это может быть необходимо.

  1. Создайте модель макета и универсальный базовый класс модели.

Я видел приложения MVC с несколькими макетами, которые можно использовать в любом представлении. Если ваши модели наследуются от базового класса, вам может понадобиться базовый класс для каждого макета. Чтобы избежать дублирования усилий, я бы создал модель макета для каждого из макетов. Тогда что-то вроде этого может сработать для вас:

abstract class ModelBase<TLayout> {
    public TLayout Layout { get; set; }
}

class Model : ModelBase<LayoutModel2> { /* model stuff here */ } 
  1. Добавьте свойства макета ViewBag.

Я могу себе представить редкие ситуации, когда размещение информации о макете в модели не является правильным вызовом. Кажется довольно распространенным явлением, когда люди используют свои модели предметной области в качестве своей модели, и вы можете, например, не захотеть смешивать данные макета/представления с бизнес-данными/данными предметной области.


Если вы решили использовать ViewBag, избегайте этого:

ViewBag.Title = "My page"
ViewBag.UserID = 123
ViewBag.UserName = "admin"
ViewBag.UserDisplayName = "Administrator"

Существуют очевидные потенциальные проблемы, такие как использование разных заглавных букв в разных местах (например, UserId вместо UserID). Менее очевидно, что кто-то может случайно установить ViewBag.UserID в string или Nullable<int>:

class SomeOtherClass {
    public string UserID { get; set; } // someone uses a string...
}

ViewBag.UserID = someOtherClassObj.UserID; // now you're in trouble.

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

ViewBag.LayoutModel = new LayoutModel { UserID = User.ID, UserName = User.Name };
person David Schwartz    schedule 11.05.2015
comment
Я также обнаружил, что немедленное приведение его к исходному типу поверх соответствующего файла .cshtml также немного облегчает проблему ViewBag. - person foresightyj; 22.09.2016
comment
Является ли то, что я ленив, очень, очень хорошей причиной? - person carrizal; 27.03.2019

Лично я выберу модель в качестве параметра, потому что модель имеет строгий тип, поэтому, когда она передается для просмотра, мы также можем контролировать, является ли наш параметр действительным или нет в ключевом слове поля. И модель — лучший способ для будущего обслуживания кода.

Ссылка для этого:

Избегайте Viewbag

person Deddy H    schedule 12.02.2014

При передаче информации в макет вашего представления

person Brad Thomas    schedule 12.02.2014

Вы можете использовать его? Конечно. Стоит ли использовать его? Зависит от того, что еще вы пытаетесь сделать. Обычно вы видите, что ViewBag зарезервирован для отправки данных, таких как заголовок страницы или что-то в этом роде. Возможно, вы захотите сохранить в своей модели параметры, которые заполняются из вашей базы данных. В основном из-за привязки модели, а также из-за того, что вы когда-либо хотели выполнить проверку модели.

person Gjohn    schedule 12.02.2014

Это зависит от сценария, если поля, которые вы хотите передать, будут просто использоваться в этом конкретном представлении, и они не могут быть сделаны как часть объекта или модели, тогда я бы выбрал пакеты просмотра, иначе я бы сделал это моделью.

person ZAK    schedule 29.05.2014
comment
пожалуйста, поясните свой ответ конкретикой и конкретными рассуждениями, почему вы что-то выбираете, а не просто мнения. - person Benjamin Trent; 29.05.2014