Jaka jest różnica między ViewData i ViewBag?

Odpowiedzi:

388

Wykorzystuje funkcję dynamiczną C # 4.0. Osiąga ten sam cel, co viewdata i należy go unikać na korzyść stosowania silnie typowanych modeli widoków (w taki sam sposób, jak należy unikać viewdata).

Zasadniczo zastępuje magiczne ciągi :

ViewData["Foo"]

o właściwościach magicznych :

ViewBag.Foo

dla których nie masz bezpieczeństwa czasu kompilacji.

Nadal obwiniam Microsoft za wprowadzenie tej koncepcji w MVC.

W nazwach właściwości rozróżniana jest wielkość liter.

Darin Dimitrov
źródło
11
W jakim celu obwiniasz Microsoft? Jeśli nie ma danych, w jaki sposób możemy powiązać listę rozwijaną z modelu. (Nie sądzę, aby dobrym pomysłem było użycie listy wyboru wewnątrz modelu)
Subin Jacob,
15
@SubinJacob Naprawdę powinieneś zadać nowe pytanie, jeśli chcesz na nie odpowiedzieć. Utworzenie listy Select jest zdecydowanie sposobem na zrobienie listy rozwijanej.
MiniRagnarok
25
Myślę, że to trochę subiektywne. Modele o silnym typie są ładne i yada yada, ale w scenariuszach, w których szybko uruchamiasz widok, ViewBag i podobne wykonują zadanie szybciej niż kontroler, widok, model, AutoMapper do ViewModel itp.
Craig Brett
11
@Darin, dlaczego „obwiniasz” Microsoft za wprowadzenie tego? To tylko narzędzie przeznaczone dla programistów. Jeśli wiesz, co robisz, możesz w pełni z tego skorzystać. Jeśli ci się nie podoba lub czujesz, że jest bardziej podatny na błędy, po prostu go nie używaj. :)
Bilal Fazlani
5
Jak sugerujesz przekazywanie danych między częściami a układem? Ludzie obwiniają się, gdy nie widzą pełnego obrazu. Wyobrażam sobie, że wszędzie masz kontrolery bazowe i modele widoku podstawowego lub obiekty statyczne / singletony. Zgadnij, lepiej naucz się korzystać z przeglądania danych i obwiniaj się za użycie niewłaściwego narzędzia do pracy.
Bart Calixto,
42

Wewnętrznie właściwości ViewBag są przechowywane jako pary nazwa / wartość w słowniku ViewData .

Uwaga: w większości przedpremierowych wersji MVC 3 właściwość ViewBag nosiła nazwę ViewModel, jak zauważono w tym fragmencie z uwag do wydania MVC 3:

(edytowane 10-8-12) Sugerowano, że opublikuję źródło tych informacji, które opublikowałem, oto źródło: http://www.asp.net/whitepapers/mvc3-release-notes#_Toc2_4

Kontrolery MVC 2 obsługują właściwość ViewData, która umożliwia przesyłanie danych do szablonu widoku przy użyciu interfejsu API słownika powiązanego z opóźnieniem. W MVC 3 można również użyć nieco prostszej składni z właściwością ViewBag, aby osiągnąć ten sam cel. Na przykład zamiast pisać ViewData [„Message”] = „text”, możesz napisać ViewBag.Message = „text”. Nie trzeba definiować żadnych silnie typowanych klas, aby korzystać z właściwości ViewBag. Ponieważ jest to właściwość dynamiczna, zamiast tego możesz po prostu uzyskać lub ustawić właściwości, które rozwiążą je dynamicznie w czasie wykonywania. Wewnętrznie właściwości ViewBag są przechowywane jako pary nazwa / wartość w słowniku ViewData. (Uwaga: w większości przedpremierowych wersji MVC 3 właściwość ViewBag została nazwana właściwością ViewModel.)

Rich Bianco
źródło
Pytanie dotyczy różnicy między, ViewDataa ViewBagnie o ViewModel.
Matthew Flaschen,
Dzięki za heads-up Matthew Flaschen, w odpowiedzi miałem literówkę i naprawiłem ją, teraz czytam „ViewData” zamiast ViewModel, co było błędem. :)
Rich Bianco,
Teraz to jest nieprawidłowe. Żadna z nich nie została przemianowana na drugą. Oboje nadal istnieją. Jeden jest dynamici wspiera ViewBag.Message. Jeden używa starej ViewData["Message"]składni.
Matthew Flaschen
1
+1 Ale z jakiego źródła cytujesz ...? Powinien naprawdę podać link.
Sam
1
Dziękuję Sam za sugestię. Dodałem link do oryginalnego źródła.
Rich Bianco,
34

ViewBag vs ViewData w MVC

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

Podobieństwa między ViewBag i ViewData:

Pomaga zachować dane podczas przechodzenia z kontrolera do widoku. Służy do przesyłania danych z kontrolera do odpowiedniego widoku. Krótkie życie oznacza, że ​​wartość staje się zerowa, gdy nastąpi przekierowanie. Wynika to z tego, że ich celem jest zapewnienie sposobu komunikacji między kontrolerami a widokami. Jest to mechanizm komunikacji w wywołaniu serwera.

Różnica między ViewBag i ViewData:

ViewData to słownik obiektów, który pochodzi z klasy ViewDataDictionary i jest dostępny za pomocą łańcuchów jako kluczy. ViewBag to dynamiczna właściwość, która wykorzystuje nowe dynamiczne funkcje w C # 4.0. ViewData wymaga rzutowania typu dla złożonych typów danych i sprawdzania wartości zerowych, aby uniknąć błędów. ViewBag nie wymaga rzutowania typu dla złożonych typów danych.

ViewBag i ViewData Przykład:

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

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

Dzwonienie w widoku

@ViewBag.Name    
@ViewData["Name"]
Arun Prakash
źródło
7
twoja odpowiedź wskazuje, typecastingale nie pokazałeś, jak odbywa się rzutowanie czcionek
Alex
31

ViewData: Wymaga rzutowania typu dla złożonych typów danych i sprawdza wartości zerowe, aby uniknąć błędów.

ViewBag: Nie wymaga rzutowania typu dla złożonych typów danych.

Rozważ następujący przykład:

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(); 
    }
}

A kod dla tego Viewjest następujący:

@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>
Naresh Ravlani
źródło
6
pomóżcie mi zrozumieć, ale myślę, że to pomyłka. to <h4>@ViewBag.emp.Name</h4> powinno się zmienić na<h4>@ViewBag.Employee.Name</h4>
Benny Margalit
24

Wszystkie odpowiedzi sugerują, że ViewBagi / lub ViewDatama przekazywać dane od ControllerdoViews , który jest dezinformacja. oba są bardzo przydatne do przesyłania danych z widoków do układu lub częściowych do widoków (lub ViewComponents itp.) Nie jest to wyłącznie kontroler.

jako domyślny przykład asp.net mają to na stronie układu:

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

i w dowolnym widoku

ViewData["Title"] = "Details";

Zatem zadając pytanie: jaka jest różnica między ViewBagiViewData ?

Najbardziej zauważalną różnicą jest ViewDatanatomiast silnie typowany słownik ViewBag typ dynamiczny.

Pamiętaj, że dane w TYM SAMYM

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

Kiedy używać jednego lub drugiego?

  • ViewBagnie obsługuje nieprawidłowych nazw C #. nie możesz uzyskać dostępu za ViewData["Key With Space"]pomocąViewBag
  • ViewBag.Something jest dynamiczny i możesz mieć problemy z wywoływaniem metod (takich jak metody rozszerzeń), które muszą znać dokładny parametr w czasie kompilacji.
  • ViewBag może sprawdzić zerowy syntaktyczny środek czyszczący: ViewBag.Person?.Name
  • ViewDatamieć wszystkie właściwości słownika, takie jak ContainsKey, Additp., więc możesz używać, ViewData.Add("somekey", "somevalue")pamiętaj, że może generować wyjątki.
  • Korzystanie ViewDataz widoków wymaga TypeCasting, podczas gdy ViewBagnie.

Znajomość subtelnych różnic, używanie jednego lub drugiego jest o wiele bardziej preferencją smakową.

Zwykle można wymyślić ViewBag.AnyKeyaliasViewData["AnyKey"]

Bart Calixto
źródło
14

Czy mogę Ci polecić, abyś nie używał?

Jeśli chcesz „wysłać” dane na ekran, wyślij obiekt o silnym typie (AKA ViewModel), ponieważ łatwiej go przetestować.

Jeśli połączysz się z jakimś „modelem” i masz losowe „viewbag” lub „viewdata”, to bardzo utrudnia automatyczne testowanie.

Jeśli ich używasz, zastanów się, w jaki sposób możesz dokonać restrukturyzacji i po prostu użyj ViewModels.

nootn
źródło
4
Ignorowanie zasady „kompilator to pierwszy test jednostkowy” w jaki sposób statyczny model widoku sprawia, że ​​kod jest bardziej testowalny niż typ dynamiczny? Podczas gdy wymóg dotyczący testów jest ważniejszy w rozwiązaniu dynamicznie typowanym, jeśli oba rozwiązania realizują tę samą liczbę i rodzaj testów, nic nie tracisz.
Darren Lewis,
Zgadzam się, to trochę niejasne. Być może w grę wchodzi inteligencja.
Joshua Ramirez
1
Jednym z przykładów może być kpina. Jeśli chcesz przetestować jednostkowo działanie kontrolera, łatwiej jest utworzyć „próbny” obiekt do przekazania i potwierdzenia, zamiast próbować stwierdzić, że jakiś ciąg został dodany do jakiegoś słownika lub jakieś pole dynamiczne ma pewną wartość - jest to podobna koncepcja do umów o świadczenie usług zawierających jeden obiekt „Żądanie” i jeden obiekt „Odpowiedź” zamiast przyjmowania wielu parametrów.
nootn
w jaki sposób przekazałbyś dane z widoku do układu, jeśli nie używasz żadnego z nich? -1
Bart Calixto
Jak to jest odpowiedź?
JSON
6

viewdata: jest słownikiem służącym do przechowywania danych między View a kontrolerem, musisz rzutować obiekt danych view na odpowiadający mu model w widoku, aby móc pobrać z niego dane ...

ViewBag: jest dynamiczną właściwością działającą podobnie do danych widoku, jednak lepiej, ponieważ nie trzeba jej rzutować na odpowiedni model przed użyciem go w widoku ...

Ahmed Elbatt
źródło
4

Poniżej znajduje się różnica punkt-punkt dotycząca ViewData, ViewBag, TempData i sesji. Kredyt / skopiowane askforprogram.in , kliknij link do przykładu kodu, o którym tu nie wspomniałem.

  1. ViewData w MVC

    • ViewData jest własnością klasy ControllerBase.
    • ViewData jest rodzajem obiektu słownikowego.
    • ViewData to kolekcja słownika klucz-wartość.
    • ViewData została wprowadzona w wersji MVC 1.0.
    • ViewData współpracuje z .Net Framework 3.5 i nowszymi wersjami.
    • Musisz wykonać konwersję typu kodu podczas wyliczania.
    • Obiekt ViewData przechowuje dane tylko dla bieżącego żądania.
  2. ViewBag w MVC

    • ViewBag jest własnością klasy ControllerBase.
    • ViewBag jest rodzajem obiektu dynamicznego.
    • ViewBag jest rodzajem obiektu.
    • ViewBag został wprowadzony w wersji MVC 3.0.
    • ViewBag współpracuje z .Net Framework 4.0 i nowszymi wersjami.
    • ViewBag korzysta z właściwości i obsługuje ją, więc nie trzeba wykonywać konwersji typu podczas wyliczania.
    • Obiekt ViewBag przechowuje dane tylko dla bieżącego żądania.
  3. TempData w MVC

    • TempData jest własnością klasy ControllerBase.
    • TempData jest rodzajem obiektu słownikowego.
    • TempData to kolekcja słownika klucz-wartość.
    • TempData została wprowadzona w wersji MVC 1.0.
    • TempData współpracuje z .Net Framework 3.5 i nowszymi wersjami.
    • Musisz wykonać konwersję typu kodu podczas wyliczania.
    • Obiekt TempData służy do danych między bieżącym żądaniem a kolejnym żądaniem.
  4. Sesja w MVC

    • Sesja jest własnością kontrolera (klasa abstrakcyjna).
    • Sesja jest rodzajem HttpSessionStateBase.
    • Sesja to kolekcja słownika klucz-wartość.
    • Sesja została wprowadzona w wersji MVC 1.0.
    • TempData współpracuje z .Net Framework 1.0 i nowszym.
    • Musisz wykonać konwersję typu kodu podczas wyliczania.
    • Obiekt sesji przechowuje dane dla wszystkich żądań. Ważne dla wszystkich wniosków, nigdy nie wygasa.
Nirju
źródło
1

Chociaż możesz nie mieć technicznej przewagi, wybierając jeden format nad drugim, powinieneś zdawać sobie sprawę z pewnych ważnych różnic między dwiema składniami. Jedną oczywistą różnicą jest to, że ViewBag działa tylko wtedy, gdy klucz, do którego uzyskujesz dostęp, jest prawidłowym identyfikatorem C #. Na przykład, jeśli umieścisz wartość w ViewData [„Key With Spaces”], nie będziesz mógł uzyskać dostępu do tej wartości za pomocą ViewBag, ponieważ kod nie zostanie skompilowany. Innym kluczowym zagadnieniem do rozważenia jest to, że nie można przekazać wartości dynamicznych jako parametrów metod rozszerzenia. Kompilator C # musi znać prawdziwy typ każdego parametru w czasie kompilacji, aby wybrać prawidłową metodę rozszerzenia. Jeśli dowolny parametr jest dynamiczny, kompilacja się nie powiedzie. Na przykład ten kod zawsze się nie powiedzie: @ Html.TextBox („name”, ViewBag.Name). Aby obejść ten problem, użyj ViewData [„Nazwa”

użytkownik2211290
źródło
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
źródło
0

W ten sposób możemy zmusić go do wykorzystania wartości do przekazania informacji między sterownikiem na inną stronę z DANYMI TEMP

użytkownik3141962
źródło
0

Jedną z głównych różnic, które zauważyłem między ViewData i ViewBag, jest:

ViewData: zwróci obiekt, bez względu na to, co do niego przypisałeś i musisz ponownie rzutować typ do pierwotnego typu.

ViewBag: wystarczy inteligentnie zwrócić dokładny typ, który mu przypisałeś, nie ma znaczenia, czy przypisałeś typ prosty (np. Int, string itp.) Czy typ złożony.

Np .: kod kontrolera.

 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; }
    }
}

Wyświetl kod.

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

Ekran wyjścia.

wprowadź opis zdjęcia tutaj

Bhanu Pratap
źródło
0

Zobacz dane

  1. ViewData służy do przekazywania danych z kontrolera do przeglądania
  2. ViewData pochodzi z klasy ViewDataDictionary i jest w zasadzie obiektem Dictionary, tj. Kluczami i Wartościami, w których Kluczami są Ciągi, a Wartościami będą obiekty.
  3. Typowanie danych jest wymagane podczas pobierania danych z ViewData ze względu na typ danych obiektu, a także sprawdzenie wartości zerowej przed rzutowaniem typu, w przeciwnym razie spowoduje to uszkodzenie aplikacji. Jeśli nastąpi przekierowanie, jego wartość staje się zerowa. Przeczytaj pełną różnicę między TempData ViewData i View Bag

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

Jatin Phulera
źródło
0
ViewData
  1. ViewData służy do przekazywania danych z kontrolera do przeglądania
  2. Wywodzi się z klasy ViewDataDictionary
  3. Jest dostępny tylko dla bieżącego żądania
  4. Wymaga rzutowania złożonego typu danych i sprawdza wartości zerowe, aby uniknąć błędów
  5. Jeśli nastąpi przekierowanie, jego wartość staje się zerowa
ViewBag
  1. ViewBag służy również do przesyłania danych z kontrolera do odpowiedniego widoku
  2. ViewBag to dynamiczna właściwość, która wykorzystuje nowe dynamiczne funkcje w C # 4.0
  3. Jest również dostępny tylko dla bieżącego żądania
  4. Jeśli nastąpi przekierowanie, jego wartość staje się zerowa
  5. Nie wymaga rzutowania typu dla złożonych typów danych
Er Pravin Suthar
źródło
0

Tutaj zarówno ViewData, jak i ViewBag są używane do przekazywania danych z kontrolera do widoku .

1. ViewData

- ViewData to obiekt słownika pochodzący z klasy ViewDataDictonary .

- Dane pozwalają tylko na jedno żądanie, wartości ViewData są usuwane, gdy nastąpi przekierowanie strony.

- Przed użyciem należy wpisać wartość ViewData.

Przykład: w kontrolerze

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

Z uwagi

@ViewData["Message"];

- W ViewData jest para taka jak Klucz i Wartość , Wiadomość jest Kluczem, a w odwróconym przecinku wartość to Wartość.

- Dane są proste, więc nie możemy tutaj użyć rzutowania typu, jeśli dane są złożone, a następnie za pomocą rzutowania typu.

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

- W widoku danych można wyodrębnić jako

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

2. ViewBag

--ViewBag używa funkcji dynamicznej. Opakowanie ViewBag wokół ViewData.

- W przypadku typu ViewBag wymagany jest rzut.

- Taki sam jak ViewData, jeśli nastąpi przekierowanie, wartość staje się pusta.

Przykład:

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

Z uwagi

@ViewBag.vbMessage

- Dla typu złożonego użyj ViewBag

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

- W widoku danych można wyodrębnić jako

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

- główna różnica polega na tym, że ViewBag nie wymaga rzutowania, ale ViewData jest wymagany.

Brijesh Mavani
źródło
-1

ViewBag i ViewData to dwa sposoby przesyłania informacji z kontrolera w celu wyświetlenia w ASP.Net MVC. Celem użycia obu mechanizmów jest zapewnienie komunikacji między kontrolerem a widokiem. Oba mają krótkie życie, co oznacza, że ​​wartość obu staje się zerowa po wystąpieniu przekierowania, tj. Po przekierowaniu strony ze strony źródłowej (gdzie ustawiamy wartość ViewBag lub ViewData) na stronę docelową, zarówno ViewBag, jak i ViewData staje się zerowy.

Pomimo tych podobieństw oba (ViewBag i ViewData) to dwie różne rzeczy, jeśli mówimy o implementacji obu. Różnice są następujące:

1.) Jeśli przeanalizujemy obie implementacje pod względem mądrości, okaże się, że ViewData jest strukturą danych słownikowych - Słownik obiektów pochodzących z ViewDataDictionary i dostępny za pomocą ciągów jako kluczy do tych wartości, podczas gdy ViewBag wykorzystuje funkcje dynamiczne wprowadzone w C # 4.0 i jest dynamiczną właściwością.

2.) Podczas uzyskiwania dostępu do wartości z ViewData musimy typecast wartości (typy danych), ponieważ są one przechowywane jako obiekty w słowniku ViewData, ale nie ma takiej potrzeby, jeśli uzyskujemy dostęp do tej wartości w przypadku ViewBag.

3.) W ViewBag możemy ustawić następującą wartość:

      ViewBag.Name = "Value"; 

i może uzyskać dostęp w następujący sposób:

          @ViewBag.Name

Podczas gdy w przypadku ViewData wartości można ustawić i uzyskać do nich dostęp w następujący sposób: Ustawienie ViewData w następujący sposób:

ViewData["Name"] = "Value";

i dostęp do takiej wartości

 @ViewData["Name"] 

Aby uzyskać więcej informacji kliknij tutaj:

Abhishek Gahlout
źródło
2
przepraszam, że przegłosowałem, ale ta odpowiedź wymaga kilku akapitów, aby powiedzieć nic użytecznego. Przydatną rzeczą, której brakuje w przyjętej odpowiedzi, byłoby zdanie „viewbag to dynamiczne opakowanie wokół viewdata”, którego nauczyłem się z rachelappel.com/...
Chris F Carroll