ViewBag, ViewData i TempData

209

Czy każde ciało może wyjaśnić, kiedy stosować

  1. TempData
  2. ViewBag
  3. ViewData

Mam wymaganie, w którym muszę ustawić wartość w kontrolerze pierwszym, że kontroler przekieruje do kontrolera dwa, a kontroler drugi wyświetli widok.

Próbowałem użyć ViewBag, wartość gubi się, kiedy osiągam kontroler drugi.

Czy mogę wiedzieć, kiedy stosować oraz jakie są zalety i wady?

Dzięki

Hari Gillala
źródło
5
To świetny post, który wyjaśnia różnice.
Beku,
1
stackoverflow.com/a/17199709/2015869
Imad Alazani
2
Sprawdź to ViewData Vs ViewBag Vs TempData
2794034

Odpowiedzi:

293

1) TempData

Umożliwia przechowywanie danych, które przetrwają dla przekierowania. Wewnętrznie używa Sesji jako magazynu kopii zapasowych, po wykonaniu przekierowania dane są automatycznie eksmitowane. Wzór jest następujący:

public ActionResult Foo()
{
    // store something into the tempdata that will be available during a single redirect
    TempData["foo"] = "bar";

    // you should always redirect if you store something into TempData to
    // a controller action that will consume this data
    return RedirectToAction("bar");
}

public ActionResult Bar()
{
    var foo = TempData["foo"];
    ...
}

2) ViewBag, ViewData

Umożliwia przechowywanie danych w akcji kontrolera, która zostanie użyta w odpowiednim widoku. Zakłada się, że akcja zwraca widok i nie przekierowuje. Mieszka tylko podczas bieżącego żądania.

Wzór jest następujący:

public ActionResult Foo()
{
    ViewBag.Foo = "bar";
    return View();
}

i w widoku:

@ViewBag.Foo

lub z ViewData:

public ActionResult Foo()
{
    ViewData["Foo"] = "bar";
    return View();
}

i w widoku:

@ViewData["Foo"]

ViewBagjest tylko dynamicznym opakowaniem ViewDatai istnieje tylko w ASP.NET MVC 3.

To powiedziawszy, żaden z tych dwóch konstruktów nigdy nie powinien być używany. Powinieneś używać modeli widoków i silnie typowanych widoków. Prawidłowy wzorzec jest następujący:

Zobacz model:

public class MyViewModel
{
    public string Foo { get; set; }
}

Akcja:

public Action Foo()
{
    var model = new MyViewModel { Foo = "bar" };
    return View(model);
}

Mocno napisany widok:

@model MyViewModel
@Model.Foo

Po tym krótkim wstępie odpowiedzmy na twoje pytanie:

Moje wymaganie polega na tym, że chcę ustawić wartość w kontrolerze, który przekieruje do ControllerTwo, a Controller2 wyświetli widok.

public class OneController: Controller
{
    public ActionResult Index()
    {
        TempData["foo"] = "bar";
        return RedirectToAction("index", "two");
    }
}

public class TwoController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Foo = TempData["foo"] as string
        };
        return View(model);
    }
}

i odpowiedni widok ( ~/Views/Two/Index.cshtml):

@model MyViewModel
@Html.DisplayFor(x => x.Foo)

Istnieją także wady stosowania TempData: jeśli użytkownik naciśnie F5 na stronie docelowej, dane zostaną utracone.

Osobiście nie używam TempData. To dlatego, że wewnętrznie korzysta z sesji, a ja wyłączam sesję w moich aplikacjach. Wolę bardziej RESZTNY sposób na osiągnięcie tego. To jest: w pierwszej akcji kontrolera, która wykonuje przekierowanie, zapisz obiekt w magazynie danych i użyj wygenerowanego unikalnego identyfikatora podczas przekierowania. Następnie w akcji docelowej użyj tego identyfikatora, aby pobrać początkowo przechowywany obiekt:

public class OneController: Controller
{
    public ActionResult Index()
    {
        var id = Repository.SaveData("foo");
        return RedirectToAction("index", "two", new { id = id });
    }
}

public class TwoController: Controller
{
    public ActionResult Index(string id)
    {
        var model = new MyViewModel
        {
            Foo = Repository.GetData(id)
        };
        return View(model);
    }
}

Widok pozostaje taki sam.

Darin Dimitrov
źródło
57
Świetna odpowiedź, ale nie zgadzam się z dogmatycznym stwierdzeniem „żaden z tych dwóch konstruktów nigdy nie powinien być używany”. Znalazłem kilka uzasadnionych zastosowań ViewBag. Na przykład ustawiam ViewBag.Titlewłaściwość we wszystkich moich _Layout.cshtmlwidokach, która jest wykorzystywana w moim pliku widoku podstawowego. Innym przypadkiem, w którym go używam, jest przekazywanie użytkownikom informacji (np. „Produkt został zapisany pomyślnie!”). Umieściłem niektóre ogólne znaczniki, Layout.cshtmlaby renderować komunikat, jeśli jest podany, i pozwala mi to ustawić ViewBag.Messagedowolną akcję. Korzystanie z właściwości ViewModel w obu przypadkach ma zbyt wiele wad.
Jesse Webb,
22
Muszę się zgodzić z Jessem, choć jest to doskonały opis, rażąco stwierdzając, że nie ma dobrego powodu, aby używać ViewBag, jest kwestią opinii, nie jest faktem. Nadużywanie ViewBag jest z pewnością złą praktyką, a niektórzy programiści wpadają w tę pułapkę, ale gustownie wykorzystana jest potężnym zasobem.
Ron DeFreitas,
1
@ ron.defreitas, w porządku, powiedz mi jeden dobry powód, dla którego miałbyś skorzystać ViewBag. Opisz konkretny scenariusz, w którym ViewBag ma jakieś zastosowanie. Skoro mówisz, że tak, cytuję potężny zasób , myślę, że masz kilka konkretnych przypadków, w których ten potężny zasób jest potężny . Ponieważ nigdy nie używałam go w swojej karierze, byłbym bardzo szczęśliwy, gdyby dowiedzieć się, jak ludzie używają tej potężnej broni.
Darin Dimitrov,
27
Mamy tutaj elitarystę. Darin, Jesse konkretnie wspomniał o jednym z takich przykładów. To, że zawsze istnieją inne sposoby robienia rzeczy, nie neguje automatycznie ich przydatności.
Djentleman,
2
@DarinDimitrov: Mam teraz scenariusz, w którym muszę przekazać pewne informacje do widoku z poziomu metody atrybutu. Korzystanie z filterContext.Controller.ViewData jest znacznie łatwiejsze niż próba przekazania go do mocno wpisanego widoku. To powiedziawszy, dziękuję za wyjaśnienie, było bardzo przydatne.
Andy,
15

ASP.NET MVC oferuje nam trzy opcje ViewData, ViewBag i TempData do przekazywania danych z kontrolera do przeglądania oraz w następnym żądaniu. ViewData i ViewBag są prawie podobne, a TempData ponosi dodatkową odpowiedzialność. Omówmy lub uzyskaj kluczowe punkty dotyczące tych trzech obiektów:

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 = "Monjurul Habib";
    return View();
}


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

Z uwagi:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData jest także słownikiem wywodzącym się z klasy TempDataDictionary i przechowywanym w krótkiej sesji życia oraz jest kluczem łańcuchowym i wartością obiektu. Różnica polega na tym, że cykl życia obiektu. TempData przechowuje informacje na czas żądania HTTP. To oznacza tylko z jednej strony na drugą. Działa to również z przekierowaniem 302/303, ponieważ znajduje się w tym samym żądaniu HTTP. Pomaga zachować dane podczas przechodzenia od jednego kontrolera do drugiego lub od jednej akcji do innej. Innymi słowy, gdy przekierowujesz, „TempData” pomaga zachować dane między tymi przekierowaniami. Używa wewnętrznie zmiennych sesji. Wykorzystanie danych tymczasowych podczas bieżącego i kolejnego żądania oznacza, że ​​jest ono używane, gdy masz pewność, że następne żądanie przekieruje do następnego widoku. Wymaga to rzutowania złożonego typu danych i sprawdzania wartości zerowych, aby uniknąć błędów.

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}

public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

Ostatnim mechanizmem jest Sesja, która działa jak ViewData, jak Słownik, który pobiera ciąg klucza i obiekt wartości. Ten jest przechowywany w klienckim pliku cookie i może być używany przez znacznie dłuższy czas. Potrzebuje także większej weryfikacji, aby nigdy nie mieć żadnych poufnych informacji. Jeśli chodzi o ViewData lub ViewBag, powinieneś używać go inteligentnie do działania aplikacji. Ponieważ każda akcja przechodzi przez cały cykl życia zwykłego żądania asp.net mvc. Możesz użyć ViewData / ViewBag w akcji podrzędnej, ale uważaj, aby nie używać go do wypełniania niepowiązanych danych, które mogą zanieczyścić kontroler.

Abdur Rahman
źródło
11

TempData

Zasadniczo jest to jak czytnik danych, po odczytaniu dane zostaną utracone.

Sprawdź to wideo

Przykład

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        String str = TempData["T"]; //Output - T
        return View();
    }
}

Jeśli zwrócisz uwagę na powyższy kod, RedirectToAction nie ma wpływu na TempData, dopóki TempData nie zostanie odczytana. Zatem po odczytaniu TempData wartości zostaną utracone.

Jak mogę zachować TempData po przeczytaniu?

Sprawdź dane wyjściowe w teście metody działania 1 i teście 2

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        string Str = Convert.ToString(TempData["T"]);
        TempData.Keep(); // Keep TempData
        return RedirectToAction("Test2");
    }

    public ActionResult Test2()
    {
        string Str = Convert.ToString(TempData["T"]); //OutPut - T
        return View();
    }
}

Jeśli zwrócisz uwagę na powyższy kod, dane nie zostaną utracone po RedirectToAction, a także po odczytaniu danych, a powodem jest to, że używamy TempData.Keep(). czy to

W ten sposób możesz utrzymać go tak długo, jak chcesz w innych kontrolerach.

ViewBag / ViewData

Dane pozostaną w odpowiednim widoku


źródło
4

TempData w Asp.Net MVC jest jedną z bardzo przydatnych funkcji. Służy do przekazywania danych z bieżącego żądania do kolejnego żądania. Innymi słowy, jeśli chcemy przesyłać dane z jednej strony na drugą, gdy nastąpi przekierowanie, możemy użyć TempData, ale musimy rozważyć kod, aby osiągnąć tę funkcję w MVC. Ponieważ życie TempData jest bardzo krótkie i trwa tylko do momentu pełnego załadowania widoku docelowego. Ale możemy użyć metody Keep (), aby utrwalić dane w TempData.

Czytaj więcej

Anil Sharma
źródło
3

ViewBag, ViewData, TempData i View State w MVC

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

ASP.NET MVC oferuje nam trzy opcje ViewData, VieBag i TempData do przekazywania danych z kontrolera do przeglądania i na następne żądanie. ViewData i ViewBag są prawie podobne, a TempData ponosi dodatkową odpowiedzialność.

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

W widoku nazywamy się jak poniżej:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Pomaga zachować dane podczas przechodzenia od jednego kontrolera do drugiego lub od jednej akcji do innej. Innymi słowy, gdy przekierowujesz, „Tempdata” pomaga zachować dane między tymi przekierowaniami. Używa wewnętrznie zmiennych sesji. TempData ma być bardzo krótkotrwałą instancją i należy jej używać tylko podczas bieżącego i kolejnych żądań

Jedynym scenariuszem, w którym użycie TempData będzie działało niezawodnie, jest przekierowanie. Wynika to z faktu, że przekierowanie zabija bieżące żądanie (i wysyła kod stanu HTTP 302 Obiekt przeniesiony do klienta), a następnie tworzy nowe żądanie na serwerze, aby obsłużyć przekierowany widok.

Wymaga to rzutowania złożonego typu danych i sprawdzania wartości zerowych, aby uniknąć błędów.

public ActionResult Index()
{   
   var model = new Review()  
   {  
      Body = "Start",  
      Rating=5  
   };  

    TempData["ModelName"] = model;    
    return RedirectToAction("About");   
} 

public ActionResult About()       
{  
    var model= TempData["ModelName"];  
    return View(model);   
}  
Arun Prakash
źródło
1
void Keep()

Calling this method with in the current action ensures that all the items in TempData are not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep(); // retains all strings values
    } 

void Keep(string key)

Calling this method with in the current action ensures that specific item in TempData is not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep("emp"); // retains only "emp" string values
    } 
Saineshwar
źródło
1

TempData będzie zawsze dostępna do pierwszego czytania, a gdy już ją przeczytasz, nie jest już dostępna, przydatne może być przekazanie szybkiej wiadomości również w celu wyświetlenia, które zniknie po pierwszym czytaniu. ViewBag Przydaje się przy szybkim przekazywaniu fragmentu danych do widoku, zwykle należy przekazać wszystkie dane do widoku przez model, ale zdarzają się przypadki, gdy model pochodzi bezpośrednio z klasy, która jest odwzorowana w bazie danych, podobnie jak struktura encji, w tym przypadku Aby zmienić swój model, aby przekazać nowy kawałek danych, możesz włożyć go do workbagu ViewData to tylko indeksowana wersja ViewBag i była używana przed MVC3

David Fawzy
źródło
0

Również zakres różni się między viewbag a temptdata. viewbag opiera się na pierwszym widoku (nie jest dzielony między metodami akcji), ale temptdata może być dzielona między metodą akcji i tylko między sobą.

Elnaz
źródło