В чем разница между ViewData и ViewBag?

Ответы:

388

Он использует динамическую функцию C # 4.0. Он достигает той же цели, что и viewdata, и его следует избегать в пользу использования строго типизированных моделей view (так же, как и viewdata, следует избегать).

Так что в основном он заменяет магические строки :

ViewData["Foo"]

с магическими свойствами :

ViewBag.Foo

для которого у вас нет безопасности времени компиляции.

Я продолжаю винить Microsoft за то, что она внедрила эту концепцию в MVC.

Имя свойств чувствительно к регистру.

Дарин димитров
источник
11
В каких целях вы обвиняете Microsoft? Если нет viewdata, как мы можем связать выпадающий список из модели. (Я не думаю, что использование selectlist внутри модели было бы хорошей идеей)
Субин Джейкоб
15
@ SubinJacob Вы действительно должны задать новый вопрос, если хотите получить ответ на этот вопрос. Создание SelectList - определенно способ сделать выпадающий список.
МиниРагнарок
25
Я думаю, что это немного субъективно. Модели со строгой типизацией хороши и хороши, но для сценариев, в которых вы быстро настраиваете и запускаете представление, ViewBag и другие выполняют работу быстрее, чем Controller, View, Model, AutoMapper to ViewModel и т. Д.
Крейг Бретт,
11
@ Darin, почему вы «обвиняете» Microsoft за то, что вы это сделали? Это просто инструмент, предоставленный разработчикам. Если вы знаете, что делаете, вы можете извлечь из этого максимум пользы. Если вам это не нравится или вы чувствуете, что оно более подвержено ошибкам, просто не используйте его. :)
Билал Фазлани
5
Как вы предлагаете передавать данные между частями и макетом? Люди обвиняют, когда они не видят полной картины. Я предполагаю, что у вас есть базовые контроллеры и модели базового вида или статические / одиночные объекты повсюду. Угадайте, что лучше научиться использовать представление данных и винить себя за использование неправильного инструмента для работы.
Барт Каликсто
42

Внутренне свойства ViewBag хранятся в виде пар имя / значение в словаре ViewData .

Примечание: в большинстве предварительных версий MVC 3 свойство ViewBag называлось ViewModel, как отмечено в этом фрагменте из примечаний к выпуску MVC 3:

(отредактировано 10-8-12) Было предложено опубликовать источник этой информации, которую я разместил, вот источник: http://www.asp.net/whitepapers/mvc3-release-notes#_Toc2_4

Контроллеры MVC 2 поддерживают свойство ViewData, которое позволяет передавать данные в шаблон представления с помощью API словаря с поздней привязкой. В MVC 3 вы также можете использовать несколько более простой синтаксис со свойством ViewBag для достижения той же цели. Например, вместо записи ViewData ["Message"] = "text", вы можете написать ViewBag.Message = "text". Вам не нужно определять строго типизированные классы, чтобы использовать свойство ViewBag. Поскольку это динамическое свойство, вы можете просто получить или установить свойства, и оно будет динамически разрешать их во время выполнения. Внутри свойства ViewBag хранятся в виде пар имя / значение в словаре ViewData. (Примечание. В большинстве предварительных версий MVC 3 свойство ViewBag называлось свойством ViewModel.)

Рич Бьянко
источник
Вопрос спрашивает разницу между ViewDataа ViewBag, а не о ViewModel.
Мэтью Флэшен
Спасибо за хедз-ап Мэттью Флэшена, в ответе была опечатка, и я исправил ее, теперь вместо ViewModel читается «ViewData», что было ошибкой. :)
Рич Бьянко
Теперь это неверно. Ни один не был переименован в другой. Они оба все еще существуют. Один есть dynamicи поддерживает ViewBag.Message. Один использует старый ViewData["Message"]синтаксис.
Мэтью Флашен
1
+1 Но из какого источника ты цитируешь ...? Должен действительно предоставить ссылку.
Сэм
1
Спасибо Сэм за предложение. Я добавил ссылку на первоисточник.
Рич Бьянко
34

ViewBag против ViewData в MVC

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

Сходства между ViewBag и ViewData:

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

Разница между ViewBag и ViewData:

ViewData - это словарь объектов, производный от класса ViewDataDictionary и доступный с использованием строк в качестве ключей. ViewBag - это динамическое свойство, использующее преимущества новых динамических функций в C # 4.0. ViewData требует преобразования типов для сложного типа данных и проверки на нулевые значения, чтобы избежать ошибки. ViewBag не требует преобразования типов для сложного типа данных.

Пример ViewBag & ViewData:

public ActionResult Index()
{   
    ViewBag.Name = "Arun Prakash";   
    return View();
}

public ActionResult Index()
{  
    ViewData["Name"] = "Arun Prakash";  
    return View();
}   

Звонок в представлении

@ViewBag.Name    
@ViewData["Name"]
Арун Пракаш
источник
7
Ваш ответ указывает, typecastingно вы не показали, как выполняется приведение типов
Alex
31

ViewDataТребуется приведение типов для сложных типов данных и проверка нулевых значений во избежание ошибок.

ViewBag: Не требует приведения типов для сложных типов данных.

Рассмотрим следующий пример:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var emp = new Employee
        {
            EmpID=101,
            Name = "Deepak",
            Salary = 35000,
            Address = "Delhi"
        };

        ViewData["emp"] = emp;
        ViewBag.Employee = emp;

        return View(); 
    }
}

И код для Viewвыглядит следующим образом:

@model MyProject.Models.EmpModel;
@{ 
 Layout = "~/Views/Shared/_Layout.cshtml"; 
 ViewBag.Title = "Welcome to Home Page";
 var viewDataEmployee = ViewData["emp"] as Employee; //need type casting
}

<h2>Welcome to Home Page</h2>
This Year Best Employee is!
<h4>@ViewBag.Employee.Name</h4>
<h3>@viewDataEmployee.Name</h3>
Нареш Равлани
источник
6
помогите мне понять, но я думаю, что есть ошибка. это <h4>@ViewBag.emp.Name</h4> должно измениться на<h4>@ViewBag.Employee.Name</h4>
Бенни Маргалит
24

Все ответы свидетельствуют о том , что ViewBagи / или ViewDataявляется передача данных Controllerв Viewsкоторой дезинформация. и то, и другое очень полезно для передачи данных из Views в Layout или Partial to Views (или ViewComponents и т. д.). Это не только для контроллера.

как образец asp.net по умолчанию, это на странице макета:

<title>@ViewData["Title"] - MyApp</title>

и в любом взгляде

ViewData["Title"] = "Details";

Итак, чтобы задать вопрос: «В чем разница между ViewBagи ViewData

Наиболее заметным отличием является ViewDataсловарь со строгой типизацией, в то время ViewBagкак это динамический тип.

Обратите внимание, что данные внутри одинаковы

ViewData["Title"] = "MyTitle";
ViewBag.Title; // returns "MyTitle";

Когда использовать тот или иной?

  • ViewBagне поддерживает недопустимые имена C #. вы не можете получить доступ ViewData["Key With Space"]сViewBag
  • ViewBag.Something является динамическим, и у вас могут возникнуть проблемы при вызове методов (например, методов расширения), которым необходимо знать точный параметр во время компиляции.
  • ViewBag Можно проверить на null синтаксический очиститель: ViewBag.Person?.Name
  • ViewDataиметь все свойства словаря, например ContainsKey, Addи т. д., чтобы вы могли использовать его, ViewData.Add("somekey", "somevalue")имейте в виду, что он может выдавать исключения.
  • Использование ViewDataon view требует TypeCasting, а ViewBagне.

Зная тонкие различия, использование того или другого - гораздо больше вкусовых предпочтений.

Обычно вы можете придумать ViewBag.AnyKeyпсевдонимViewData["AnyKey"]

Барт Каликсто
источник
14

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

Если вы хотите «отправить» данные на экран, отправьте строго типизированный объект (AKA ViewModel), потому что его проще тестировать.

Если вы привязываетесь к какому-либо типу «Модель» и имеете случайные элементы «viewbag» или «viewdata», то это делает автоматизированное тестирование очень трудным.

Если вы используете их, подумайте, как вы можете реструктурировать и просто использовать ViewModels.

nootn
источник
4
Не обращая внимания на принцип «компилятор - первый модульный тест», как модель представления со статической типизацией делает ваш код более тестируемым, чем динамический тип? Хотя требование к тестам является более важным в динамически типизированном решении, если оба решения реализуют одинаковое количество и тип тестов, вы ничего не теряете.
Даррен Льюис
Я согласен, это немного расплывчато. Возможно, intellisense участвует.
Джошуа Рамирес
1
Одним из примеров будет насмешка. Если вы хотите выполнить модульное тестирование действия контроллера, проще создать «фиктивный» объект для обхода и утверждения, а не пытаться утверждать, что какая-то строка была добавлена ​​в некоторый словарь или какое-то динамическое поле имеет какое-то значение - это концепция, аналогичная контрактам на обслуживание, имеющим один объект «Запрос» и один объект «Ответ», вместо принятия нескольких параметров.
Nootn
как бы вы передавали данные из View в Layout, если не используете ни того, ни другого? -1
Барт Каликсто
Как это ответ?
JSON
11

Есть некоторые тонкие различия, которые означают, что вы можете использовать ViewData и ViewBag немного иначе, чем представление. Одно из преимуществ изложено в этом посте http://weblogs.asp.net/hajan/archive/2010/12/11/viewbag-dynamic-in-asp-net-mvc-3-rc-2.aspx и показывает, что кастинг можно избежать в примере, используя ViewBag вместо ViewData.

Алан Макдональд
источник
6

viewdata: словарь, используемый для хранения данных между View и контроллером, вам нужно привести объект данных view к его соответствующей модели в представлении, чтобы иметь возможность извлекать данные из него ...

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

Ахмед Эльбатт
источник
4

Ниже приведено различие между ViewData, ViewBag, TempData & Session. Credit / coped askforprogram.in , перейдите по ссылке для примера кода, который я не упомянул здесь.

  1. ViewData в MVC

    • ViewData является свойством класса ControllerBase.
    • ViewData - это тип объекта словаря.
    • ViewData - это словарь-коллекция ключей.
    • ViewData была представлена ​​в версии MVC 1.0.
    • ViewData работает с .Net Framework 3.5 и выше.
    • Нужно сделать преобразование типа кода при перечислении.
    • Объект ViewData хранит данные только для текущего запроса.
  2. ViewBag в MVC

    • ViewBag является свойством класса ControllerBase.
    • ViewBag - это тип динамического объекта.
    • ViewBag - это тип объекта.
    • ViewBag был представлен в версии MVC 3.0.
    • ViewBag работает с .Net Framework 4.0 и выше.
    • ViewBag использует свойство и обрабатывает его, поэтому нет необходимости выполнять преобразование типов при перечислении.
    • Объект ViewBag хранит данные только для текущего запроса.
  3. TempData в MVC

    • TempData является свойством класса ControllerBase.
    • TempData - это тип объекта словаря.
    • TempData - это словарь-ключ.
    • TempData была введена в версии MVC 1.0.
    • TempData работает с .Net Framework 3.5 и выше.
    • Нужно сделать преобразование типа кода при перечислении.
    • Объект TempData используется для данных между текущим запросом и последующим запросом.
  4. Сессия в MVC

    • Сессия является собственностью контроллера (абстрактный класс).
    • Сессия является типом HttpSessionStateBase.
    • Сессия - это словарь-ключ.
    • Сессия была введена в версии MVC 1.0.
    • TempData работает с .Net Framework 1.0 и выше.
    • Нужно сделать преобразование типа кода при перечислении.
    • Объект сеанса хранит данные для всех запросов. Действительно для всех запросов, никогда не истекает.
Nirju
источник
1

Хотя у вас может не быть технического преимущества при выборе одного формата над другим, вы должны знать о некоторых важных различиях между двумя синтаксисами. Одно очевидное отличие состоит в том, что ViewBag работает только тогда, когда ключ, к которому вы обращаетесь, является действительным идентификатором C #. Например, если вы поместите значение в ViewData ["Key With Spaces"], вы не сможете получить доступ к этому значению с помощью ViewBag, потому что код не будет компилироваться. Другой ключевой вопрос, который следует учитывать, - это то, что вы не можете передавать динамические значения в качестве параметров в методы расширения. Компилятор C # должен знать реальный тип каждого параметра во время компиляции, чтобы выбрать правильный метод расширения. Если какой-либо параметр является динамическим, компиляция не удастся. Например, этот код всегда завершится ошибкой: @ Html.TextBox («имя», ViewBag.Name). Чтобы обойти это, используйте ViewData ["Name"

user2211290
источник
0
public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}

public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

In View:

@ViewBag.Name 
@ViewData["Name"] 
dilipkumar1007
источник
0

Таким образом, мы можем заставить его использовать значения для передачи информации между контроллером на другую страницу с TEMP DATA

user3141962
источник
0

Одно основное отличие, которое я заметил между ViewData и ViewBag:

ViewData: он будет возвращать объект независимо от того, что вы в него назначили, и вам нужно будет снова привести тип к исходному типу

ViewBag: он достаточно умен, чтобы возвращать точный тип, который вы ему присвоили, не имеет значения, назначен ли вам простой тип (например, int, string и т. Д.) Или сложный тип.

Пример: код контроллера.

 namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Products p1 = new Products();
            p1.productId = 101;
            p1.productName = "Phone";
            Products p2 = new Products();
            p2.productId = 102;
            p2.productName = "laptop";

            List<Products> products = new List<Products>();
            products.Add(p1);
            products.Add(p2);
            ViewBag.Countries = products;
            return View();
        }
    }
    public class Products
    {
        public int productId { get; set; }
        public string productName { get; set; }
    }
}

Посмотреть код.

<ul>
            @foreach (WebApplication1.Controllers.Products item in ViewBag.Countries)
            {
            <li>@item.productId &nbsp;&nbsp;&nbsp;@item.productName</li>
            }
        </ul>

Выходной экран.

введите описание изображения здесь

Бхану Пратап
источник
0

Просмотр данных

  1. ViewData используется для передачи данных из контроллера для просмотра
  2. ViewData является производным от класса ViewDataDictionary и в основном представляет собой объект Dictionary, т.е. ключи и значения, где ключи представляют собой строку, а значения - объекты.
  3. При получении данных из ViewData требуется типизация данных из-за его типа данных Object, а также проверки нулевого значения перед приведением типа, в противном случае это нарушит работу приложения. Если происходит перенаправление, то его значение становится равным нулю. Полная разность чтения между TempData ViewData и View Bag

http://www.gurujipoint.com/2017/09/view-data-viewbag-and-tempdata.html

Джатин Фулера
источник
0
ViewData
  1. ViewData используется для передачи данных из контроллера для просмотра
  2. Он является производным от класса ViewDataDictionary
  3. Доступно только для текущего запроса
  4. Требуется приведение типов для сложного типа данных и проверка на нулевые значения, чтобы избежать ошибок
  5. Если происходит перенаправление, его значение становится нулевым
ViewBag
  1. ViewBag также используется для передачи данных из контроллера в соответствующее представление
  2. ViewBag - это динамическое свойство, использующее преимущества новых динамических функций в C # 4.0.
  3. Он также доступен только для текущего запроса
  4. Если происходит перенаправление, его значение становится нулевым
  5. Не требует преобразования типов для сложного типа данных
Эр Правин Сутар
источник
0

Здесь и ViewData, и ViewBag используются для передачи данных из Controller в View .

1. ViewData

- ViewData - объект словаря, производный от класса ViewDataDictonary .

- Данные допускают только один запрос, значения ViewData очищаются при перенаправлении страницы.

- Значение ViewData должно быть напечатано cate перед использованием.

Пример: в контроллере

public ActionResult PassingDatatoViewWithViewData()
{
      ViewData["Message"] = "This message shown in view with the ViewData";
      return View();
}

Ввиду

@ViewData["Message"];

- ViewData - это пара, такая как Key и Value , Message - это Key, а в кавычках значение - Value.

- Данные просты, поэтому мы не можем использовать здесь приведение типов, если данные сложны, тогда используется приведение типов.

public ActionResult PassingDatatoViewWithViewData()
{
      var type= new List<string>
    {
        "MVC",
        "MVP",
        "MVVC"
    };
    ViewData["types"] = type;
    return View();
}

- В View данные могут быть извлечены как

<ul>
        @foreach (var items in (List<string>)ViewData["types"])
        {
         <li>@items</li>
        }
  </ul>

2. ViewBag

--ViewBag использует динамическую особенность. Оболочка ViewBag вокруг ViewData.

- В ViewBag тип приведения не требуется.

- То же, что и ViewData, если происходит перенаправление, значение становится нулевым.

Пример:

public ActionResult PassingDatatoViewWithViewBag()
{
          ViewData.Message = "This message shown in view with the ViewBag";
          return View();
}

Ввиду

@ViewBag.vbMessage

- Для сложного типа используйте ViewBag

public ActionResult PassingDatatoViewWithViewBag()
{
          var type= new List<string>
        {
            "MVC",
            "MVP",
            "MVVC"
        };
        ViewBag.types = type;
        return View();
 }

- В View данные могут быть извлечены как

<ul>
       @foreach (var items in ViewBag.types)
       {
         <li>@items</li>
       }
</ul>

- главное различие заключается в том, что ViewBag не требует приведения типов, но ViewData требует приведения типов.

Бриеш Мавани
источник
-1

ViewBag и ViewData - это два средства, которые используются для передачи информации от контроллера для просмотра в ASP.Net MVC. Цель использования обоих механизмов - обеспечить связь между контроллером и View. Оба имеют короткую жизнь, то есть значение обоих становится нулевым, как только происходит перенаправление, т. Е. После перенаправления страницы с исходной страницы (где мы устанавливаем значение ViewBag или ViewData) на целевую страницу, как ViewBag, так и ViewData становится нулевым

Несмотря на то, что эти сходства (ViewBag и ViewData) являются двумя разными вещами, если говорить о реализации обоих. Различия заключаются в следующем:

1.) Если мы проанализируем оба варианта реализации, то обнаружим, что ViewData - это структура данных словаря - Словарь объектов, производный от ViewDataDictionary и доступный с использованием строк в качестве ключей для этих значений, тогда как ViewBag использует динамические функции, представленные в C # 4.0, и это динамическое свойство.

2.) Получая доступ к значениям из ViewData, нам нужно типизировать значения (типы данных), поскольку они хранятся в виде объектов в словаре ViewData, но такой необходимости нет, если мы обращаемся к этому значению в случае ViewBag.

3.) В ViewBag мы можем установить значение следующим образом:

      ViewBag.Name = "Value"; 

и может получить доступ следующим образом:

          @ViewBag.Name

В то время как в случае ViewData значения могут быть установлены и доступны следующим образом: Настройка ViewData следующим образом:

ViewData["Name"] = "Value";

и доступ к значению, как это

 @ViewData["Name"] 

Для более подробной информации нажмите здесь:

Абхишек Галоут
источник
2
извините, я проголосовал, но этот ответ занимает несколько параграфов, чтобы ничего не сказать полезного. Полезной вещью, отсутствующей в принятом ответе, было бы предложение «viewbag - это динамическая оболочка вокруг viewdata», которое я узнал от rachelappel.com/…
Крис Ф. Кэрролл