ViewBag, ViewData e TempData


209

Qualcuno potrebbe spiegare quando usare

  1. TempData
  2. ViewBag
  3. Viewdata

Ho un requisito, in cui devo impostare un valore in un controller, quel controller reindirizzerà al controller due e il controller due visualizzerà la vista.

Ho provato a usare ViewBag, il valore si perde quando raggiungo il controller due.

Posso sapere quando utilizzare e vantaggi o svantaggi?

Grazie


5
Questo è un ottimo post che spiega le differenze.
Beku,

1
stackoverflow.com/a/17199709/2015869
Imad Alazani,

Risposte:


293

1) TempData

Consente di archiviare i dati che sopravviveranno per un reindirizzamento. Internamente utilizza la Sessione come archivio di backup, dopo aver effettuato il reindirizzamento i dati vengono automaticamente sfrattati. Il modello è il seguente:

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

Consente di archiviare i dati in un'azione del controller che verrà utilizzata nella vista corrispondente. Ciò presuppone che l'azione restituisca una vista e non reindirizzi. Vive solo durante la richiesta corrente.

Il modello è il seguente:

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

e nella vista:

@ViewBag.Foo

o con ViewData:

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

e nella vista:

@ViewData["Foo"]

ViewBagè solo un wrapper dinamico ViewDataed esiste solo in ASP.NET MVC 3.

Detto questo, nessuno di questi due costrutti dovrebbe mai essere usato. È necessario utilizzare modelli di visualizzazione e visualizzazioni fortemente tipizzate. Quindi il modello corretto è il seguente:

Vedi modello:

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

Azione:

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

Vista fortemente tipizzata:

@model MyViewModel
@Model.Foo

Dopo questa breve introduzione rispondiamo alla tua domanda:

Il mio requisito è che voglio impostare un valore in un controller, quel controller reindirizzerà su ControllerTwo e Controller2 visualizzerà la vista.

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

e la vista corrispondente ( ~/Views/Two/Index.cshtml):

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

Ci sono anche degli svantaggi nell'utilizzo di TempData: se l'utente preme F5 sulla pagina di destinazione, i dati andranno persi.

Personalmente non uso nemmeno TempData. È perché internamente utilizza Session e disabilito la sessione nelle mie applicazioni. Preferisco un modo più RESTful per raggiungere questo obiettivo. Che è: nella prima azione del controller che esegue l'archivio di reindirizzamento l'oggetto nell'archivio dati e l'utente l'id univoco generato durante il reindirizzamento. Quindi sull'azione di destinazione utilizzare questo ID per recuperare l'oggetto inizialmente memorizzato:

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

La vista rimane la stessa.


57
Ottima risposta, ma non sono d'accordo con l'affermazione dogmatica "nessuno di questi due costrutti dovrebbe mai essere usato". Ho trovato un paio di usi legittimi per il ViewBag. Ad esempio, ho impostato una ViewBag.Titleproprietà su tutte le mie visualizzazioni che viene utilizzata nel mio _Layout.cshtmlfile di visualizzazione di base. Un altro caso in cui lo uso è l'invio di messaggi informativi (ad es. "Prodotto salvato correttamente!") Agli utenti. Ho inserito un markup generico Layout.cshtmlper rendere un messaggio se fornito e questo mi permette di impostare ViewBag.Messagequalsiasi azione. L'uso di una proprietà ViewModel per entrambi i casi presenta troppi svantaggi.
Jesse Webb,

22
Dovrei essere d'accordo con Jesse, sebbene questa sia una descrizione eccellente, affermando chiaramente che non c'è una buona ragione per usare ViewBag è una questione di opinione, non di fatto. È certamente una cattiva pratica abusare del ViewBag e alcuni sviluppatori cadono in questa trappola, ma usata con gusto è una potente risorsa.
Ron DeFreitas,

1
@ ron.defreitas, va bene, dimmi allora un buon motivo per usarlo ViewBag. Descrivi uno scenario specifico del mondo reale, quando ViewBag ha qualche utilità. Dal momento che stai dicendo che lo è, cito una risorsa potente , immagino tu abbia alcuni casi specifici in cui questa potente risorsa è potente . Dato che non l'ho mai usato in carriera, sarei molto felice di sapere come le persone usano questa potente arma.
Darin Dimitrov,

27
Abbiamo un elitario qui. Darin, Jesse ha menzionato in particolare uno di questi esempi. Solo perché ci sono sempre altri modi di fare le cose non nega automaticamente la loro utilità.
Djentleman,

2
@DarinDimitrov: ho uno scenario in questo momento in cui ho bisogno di passare alcune informazioni alla vista all'interno di un metodo di attributo. L'uso di filterContext.Controller.ViewData è sostanzialmente più semplice rispetto al tentativo di passarlo a una vista fortemente tipizzata. Detto questo, grazie per la tua spiegazione, è stato molto utile.
Andy,

15

ASP.NET MVC ci offre tre opzioni ViewData, ViewBag e TempData per il passaggio dei dati dal controller alla vista e nella richiesta successiva. ViewData e ViewBag sono quasi simili e TempData ha ulteriori responsabilità. Discutiamo o otteniamo punti chiave su questi tre oggetti:

Somiglianze tra ViewBag e ViewData:

  • Aiuta a conservare i dati quando si passa dal controller alla visualizzazione.
  • Utilizzato per passare i dati dal controller alla vista corrispondente.
  • Vita breve significa che il valore diventa nullo quando si verifica il reindirizzamento. Questo perché il loro obiettivo è fornire un modo per comunicare tra controller e viste. È un meccanismo di comunicazione all'interno della chiamata del server.

Differenza tra ViewBag e ViewData:

  • ViewData è un dizionario di oggetti che deriva dalla classe ViewDataDictionary e accessibile usando le stringhe come chiavi.
  • ViewBag è una proprietà dinamica che sfrutta le nuove funzionalità dinamiche in C # 4.0.
  • ViewData richiede la tipografia per tipi di dati complessi e verifica la presenza di valori null per evitare errori.
  • ViewBag non richiede il typecasting per tipi di dati complessi.

Esempio di ViewBag e ViewData:

public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}


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

In vista:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData è anche un dizionario derivato dalla classe TempDataDictionary e memorizzato in una sessione di breve durata ed è una chiave stringa e un valore oggetto. La differenza è che il ciclo di vita dell'oggetto. TempData conserva le informazioni per il momento di una richiesta HTTP. Questo significa solo da una pagina all'altra. Funziona anche con un reindirizzamento 302/303 perché è nella stessa richiesta HTTP. Aiuta a mantenere i dati quando si passa da un controller all'altro controller o da un'azione all'altra. In altre parole, quando si reindirizza, "TempData" aiuta a mantenere i dati tra quei reindirizzamenti. Utilizza internamente le variabili di sessione. L'uso dei dati temporanei durante la richiesta corrente e successiva significa che viene utilizzato solo quando si è certi che la richiesta successiva verrà reindirizzata alla vista successiva. Richiede la tipografia per tipi di dati complessi e verifica la presenza di valori null per evitare errori.

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

L'ultimo meccanismo è la sessione che funziona come ViewData, come un dizionario che accetta una stringa per chiave e oggetto per valore. Questo è memorizzato nel cookie del client e può essere utilizzato per molto più tempo. Ha anche bisogno di ulteriori verifiche per non avere mai informazioni riservate. Per quanto riguarda ViewData o ViewBag, è necessario utilizzarlo in modo intelligente per le prestazioni dell'applicazione. Perché ogni azione passa attraverso l'intero ciclo di vita della normale richiesta di mvc asp.net. È possibile utilizzare ViewData / ViewBag nell'azione figlio ma fare attenzione a non utilizzarlo per popolare i dati non correlati che possono inquinare il controller.


11

TempData

Fondamentalmente è come un DataReader, una volta letto, i dati andranno persi.

Guarda questo video

Esempio

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

Se si presta attenzione al codice sopra, RedirectToAction non ha alcun impatto su TempData fino a quando non viene letto TempData. Quindi, una volta letto TempData, i valori andranno persi.

Come posso conservare TempData dopo aver letto?

Controllare l'output in Metodo di prova Test 1 e Test 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();
    }
}

Se si presta attenzione al codice sopra riportato, i dati non vengono persi dopo RedirectToAction, nonché dopo aver letto i dati e il motivo è che stiamo utilizzando TempData.Keep(). è questo

In questo modo puoi farlo persistere finché lo desideri anche in altri controller.

ViewBag / Viewdata

I dati persistono alla vista corrispondente


4

TempData in Asp.Net MVC è una delle funzionalità molto utili. Viene utilizzato per passare i dati dalla richiesta corrente alla richiesta successiva. In altre parole, se vogliamo inviare dati da una pagina a un'altra mentre si verifica il reindirizzamento, possiamo usare TempData, ma dobbiamo fare un po 'di considerazione nel codice per ottenere questa funzione in MVC. Perché la durata di TempData è molto breve e rimane solo fino a quando la vista target non è completamente caricata. Ma possiamo usare il metodo Keep () per mantenere i dati in TempData.

Leggi di più


3

ViewBag, ViewData, TempData e View State in MVC

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

ASP.NET MVC ci offre tre opzioni ViewData, VieBag e TempData per il passaggio dei dati dal controller alla vista e nella richiesta successiva. ViewData e ViewBag sono quasi simili e TempData ha ulteriori responsabilità.

Somiglianze tra ViewBag e ViewData:

Aiuta a conservare i dati quando si passa dal controller alla visualizzazione. Utilizzato per passare i dati dal controller alla vista corrispondente. Vita breve significa che il valore diventa nullo quando si verifica il reindirizzamento. Questo perché il loro obiettivo è fornire un modo per comunicare tra controller e viste. È un meccanismo di comunicazione all'interno della chiamata del server.

Differenza tra ViewBag e ViewData:

ViewData è un dizionario di oggetti che deriva dalla classe ViewDataDictionary e accessibile usando le stringhe come chiavi. ViewBag è una proprietà dinamica che sfrutta le nuove funzionalità dinamiche in C # 4.0. ViewData richiede la tipografia per tipi di dati complessi e verifica la presenza di valori null per evitare errori. ViewBag non richiede il typecasting per tipi di dati complessi.

Esempio di ViewBag e ViewData:

public ActionResult Index()

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

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

In Visualizza, chiamiamo come di seguito:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Aiuta a conservare i dati quando si passa da un controller all'altro controller o da un'azione all'altra. In altre parole, quando si reindirizza, "Tempdata" aiuta a mantenere i dati tra quei reindirizzamenti. Utilizza internamente le variabili di sessione. TempData è pensato per essere un'istanza di breve durata e dovresti usarla solo durante le richieste correnti e successive

L'unico scenario in cui l'utilizzo di TempData funzionerà in modo affidabile è il reindirizzamento. Questo perché un reindirizzamento uccide la richiesta corrente (e invia il codice di stato HTTP 302 Oggetto spostato al client), quindi crea una nuova richiesta sul server per servire la vista reindirizzata.

Richiede la tipografia per tipi di dati complessi e verifica la presenza di valori null per evitare errori.

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

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
    } 

1

TempData sarà sempre disponibile fino alla prima lettura, una volta letto non sarà più disponibile può essere utile per passare un messaggio rapido anche per vedere che sparirà dopo la prima lettura. ViewBag È più utile quando si passa rapidamente un pezzo di dati alla vista, normalmente è necessario passare tutti i dati alla vista attraverso il modello, ma ci sono casi in cui si modella direttamente dalla classe che è mappata nel database come framework di entità in quel caso per cambiare il tuo modello e passare un nuovo dato, puoi incollarlo nel viewbag ViewData è solo una versione indicizzata di ViewBag ed è stato usato prima di MVC3


0

Inoltre, l'ambito di applicazione è diverso tra viewbag e temptdata. viewbag si basa sulla prima vista (non condivisa tra i metodi di azione) ma i temptdata possono essere condivisi tra un metodo di azione e solo l'uno con l'altro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.