ViewBag, ViewData e TempData


209

Alguém poderia explicar quando usar

  1. TempData
  2. ViewBag
  3. Ver dados

Eu tenho um requisito, onde eu preciso definir um valor em um controlador um, que o controlador redirecione para o Controlador Dois e o Controlador Dois renderize a Visualização.

Eu tentei usar o ViewBag, o valor se perde quando chego ao controlador dois.

Posso saber quando usar e vantagens ou desvantagens?

obrigado


5
Este é um ótimo post que explica as diferenças.
Beku 3/11

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

Respostas:


293

1) TempData

Permite armazenar dados que sobreviverão a um redirecionamento. Internamente, ele usa a Sessão como armazenamento de backup, depois que o redirecionamento é feito, os dados são despejados automaticamente. O padrão é o seguinte:

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

Permite armazenar dados em uma ação do controlador que será usada na visualização correspondente. Isso pressupõe que a ação retorne uma exibição e não redirecione. Vive apenas durante a solicitação atual.

O padrão é o seguinte:

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

e na vista:

@ViewBag.Foo

ou com ViewData:

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

e na vista:

@ViewData["Foo"]

ViewBagé apenas um invólucro dinâmico ViewDatae existe apenas no ASP.NET MVC 3.

Dito isto, nenhuma dessas duas construções deve ser usada. Você deve usar modelos de vista e vistas fortemente tipadas. Portanto, o padrão correto é o seguinte:

Ver modelo:

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

Açao:

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

Visualização fortemente tipada:

@model MyViewModel
@Model.Foo

Após esta breve introdução, vamos responder à sua pergunta:

Meu requisito é que eu quero definir um valor em um controlador, esse controlador será redirecionado para ControllerTwo e Controller2 renderizará a View.

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 a vista correspondente ( ~/Views/Two/Index.cshtml):

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

Também existem desvantagens em usar o TempData: se o usuário pressionar F5 na página de destino, os dados serão perdidos.

Pessoalmente, também não uso o TempData. É porque internamente ele usa Session e eu desabilito a sessão nos meus aplicativos. Eu prefiro uma maneira mais RESTful de conseguir isso. O que é: na primeira ação do controlador que executa o redirecionamento, armazene o objeto no seu repositório de dados e use o ID exclusivo gerado ao redirecionar. Em seguida, na ação de destino, use esse ID para recuperar o objeto armazenado inicialmente:

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

A vista permanece a mesma.


57
Ótima resposta, mas não concordo com a afirmação dogmática de "nenhuma dessas duas construções deve ser usada". Encontrei alguns usos legítimos para o ViewBag. Por exemplo, defino uma ViewBag.Titlepropriedade em todas as minhas Views que é usada no meu _Layout.cshtmlarquivo de visualização base. Outro caso em que eu o uso é fornecer mensagens informativas (por exemplo, "Produto salvo com sucesso!") Para os usuários. Coloquei alguma marcação genérica Layout.cshtmlpara renderizar uma mensagem, se fornecida, e isso me permite definir ViewBag.Messagequalquer ação. O uso de uma propriedade ViewModel para ambos os casos tem muitas desvantagens.
perfil completo de Jesse Webb

22
Eu teria que concordar com Jesse, embora essa seja uma descrição excelente, afirmando descaradamente que não há boas razões para usar o ViewBag. É uma questão de opinião, não de fato. Certamente é uma prática ruim usar o ViewBag em excesso, e alguns desenvolvedores caem nessa armadilha, mas, com bom gosto, é um recurso poderoso.
Ron DeFreitas

1
@ ron.defreitas, tudo bem, diga-me uma boa razão para você usar ViewBag. Por favor, descreva um cenário específico do mundo real, quando o ViewBag for útil. Como você está dizendo que sim, cito um recurso poderoso , acho que você tem alguns casos específicos em que esse recurso poderoso é poderoso . Como nunca o usei em minha carreira, ficaria muito feliz em saber como as pessoas estão usando essa arma poderosa .
Darin Dimitrov

27
Temos um elitista aqui. Darin, Jesse mencionou especificamente um exemplo. Só porque sempre há outras maneiras de fazer as coisas não nega automaticamente sua utilidade.
Djentleman

2
@DarinDimitrov: Eu tenho um cenário no momento em que preciso passar algumas informações para a visualização de dentro de um método de atributo. O uso de filterContext.Controller.ViewData é substancialmente mais fácil do que tentar transmiti-lo para uma exibição fortemente tipada. Dito isto, obrigado por sua explicação, foi muito útil.
21413 Andy

15

O ASP.NET MVC oferece três opções: ViewData, ViewBag e TempData para passar dados do controlador para exibição e na próxima solicitação. ViewData e ViewBag são quase semelhantes e TempData executa responsabilidades adicionais. Vamos discutir ou obter pontos-chave sobre esses três objetos:

Semelhanças entre ViewBag e ViewData:

  • Ajuda a manter os dados quando você passa do controlador para a exibição.
  • Usado para passar dados do controlador para a visualização correspondente.
  • Vida curta significa que o valor se torna nulo quando o redirecionamento ocorre. Isso ocorre porque o objetivo deles é fornecer uma maneira de se comunicar entre controladores e visualizações. É um mecanismo de comunicação dentro da chamada do servidor.

Diferença entre ViewBag e ViewData:

  • ViewData é um dicionário de objetos que é derivado da classe ViewDataDictionary e acessível usando cadeias de caracteres como chaves.
  • O ViewBag é uma propriedade dinâmica que tira proveito dos novos recursos dinâmicos do C # 4.0.
  • O ViewData requer a conversão de tipos de dados complexos e verifica valores nulos para evitar erros.
  • O ViewBag não requer conversão de tipo para dados complexos.

Exemplo de ViewBag e ViewData:

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


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

Em vista:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData também é um dicionário derivado da classe TempDataDictionary e armazenado em uma sessão de vida curta e é uma chave de string e um valor de objeto. A diferença é que o ciclo de vida do objeto. TempData mantém as informações durante o tempo de uma solicitação HTTP. Isso significa apenas de uma página para outra. Isso também funciona com um redirecionamento 302/303 porque está na mesma solicitação HTTP. Ajuda a manter os dados quando você move de um controlador para outro controlador ou de uma ação para outra ação. Em outras palavras, quando você redireciona, o "TempData" ajuda a manter os dados entre esses redirecionamentos. Ele usa internamente variáveis ​​de sessão. O uso de dados temporários durante a solicitação atual e subsequente significa apenas que é usado quando você tem certeza de que a próxima solicitação será redirecionada para a próxima visualização. Requer conversão de tipo para dados complexos e verifique se há valores nulos para evitar erros.

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

O último mecanismo é a sessão que funciona como o ViewData, como um dicionário que usa uma string como chave e o objeto como valor. Este é armazenado no Cookie do cliente e pode ser usado por muito mais tempo. Ele também precisa de mais verificação para nunca ter nenhuma informação confidencial. Em relação ao ViewData ou ViewBag, você deve usá-lo de forma inteligente para o desempenho do aplicativo. Porque cada ação passa por todo o ciclo de vida da solicitação regular do asp.net mvc. Você pode usar o ViewData / ViewBag em sua ação filho, mas tenha cuidado para não usá-lo para preencher os dados não relacionados que podem poluir seu controlador.


11

TempData

Basicamente, é como um DataReader, uma vez lido, os dados serão perdidos.

Veja este vídeo

Exemplo

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 você prestar atenção ao código acima, RedirectToAction não terá impacto sobre o TempData até que o TempData seja lido. Portanto, depois que o TempData for lido, os valores serão perdidos.

Como posso manter o TempData após a leitura?

Verifique a saída no Método de Ação Teste 1 e Teste 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 você prestar atenção ao código acima, os dados não serão perdidos após o RedirectToAction, bem como após a leitura dos dados e o motivo é: estamos usando TempData.Keep(). é aquele

Dessa maneira, você pode persistir o tempo que desejar em outros controladores também.

ViewBag / ViewData

Os dados persistirão para a visualização correspondente


4

TempData no Asp.Net MVC é um dos recursos muito úteis. É usado para passar dados da solicitação atual para a solicitação subsequente. Em outras palavras, se queremos enviar dados de uma página para outra enquanto o redirecionamento ocorre, podemos usar o TempData, mas precisamos considerar o código para obter esse recurso no MVC. Como a vida útil do TempData é muito curta e permanece apenas até que a exibição de destino esteja totalmente carregada. Mas, podemos usar o método Keep () para manter os dados no TempData.

consulte Mais informação


3

ViewBag, ViewData, TempData e View State no MVC

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

O ASP.NET MVC oferece três opções: ViewData, VieBag e TempData, para passar dados do controlador para exibição e na próxima solicitação. ViewData e ViewBag são quase semelhantes e TempData executa responsabilidades adicionais.

Semelhanças entre ViewBag e ViewData:

Ajuda a manter os dados quando você passa do controlador para a exibição. Usado para passar dados do controlador para a visualização correspondente. Vida curta significa que o valor se torna nulo quando o redirecionamento ocorre. Isso ocorre porque o objetivo deles é fornecer uma maneira de se comunicar entre controladores e visualizações. É um mecanismo de comunicação dentro da chamada do servidor.

Diferença entre ViewBag e ViewData:

ViewData é um dicionário de objetos que é derivado da classe ViewDataDictionary e acessível usando cadeias de caracteres como chaves. O ViewBag é uma propriedade dinâmica que tira proveito dos novos recursos dinâmicos do C # 4.0. O ViewData requer a conversão de tipos de dados complexos e verifica valores nulos para evitar erros. O ViewBag não requer conversão de tipo para dados complexos.

Exemplo de ViewBag e ViewData:

public ActionResult Index()

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

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

Na Vista, chamamos como abaixo:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Ajuda a manter os dados quando você move de um controlador para outro controlador ou de uma ação para outra ação. Em outras palavras, quando você redireciona, "Tempdata" ajuda a manter os dados entre esses redirecionamentos. Ele usa internamente variáveis ​​de sessão. TempData deve ser uma instância de vida muito curta, e você deve usá-lo apenas durante as solicitações atuais e subsequentes.

O único cenário em que o uso do TempData funcionará de maneira confiável é quando você está redirecionando. Isso ocorre porque um redirecionamento mata a solicitação atual (e envia o código de status HTTP 302 Objeto Movido para o cliente) e cria uma nova solicitação no servidor para atender à exibição redirecionada.

Requer conversão de tipo para dados complexos e verifique se há valores nulos para evitar erros.

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

O TempData estará sempre disponível até a primeira leitura, uma vez que você não estiver mais disponível, poderá ser útil passar uma mensagem rápida também para ver se ela desapareceu após a primeira leitura. ViewBag É mais útil ao passar rapidamente dados para a visualização, normalmente você deve passar todos os dados para a visualização através do modelo, mas há casos em que você modela vindo diretamente da classe que é mapeada no banco de dados como estrutura de entidade. o que mudar seu modelo para passar um novo dado, você pode colocar isso no viewbag ViewData é apenas uma versão indexada do ViewBag e foi usada antes do MVC3


0

Também o escopo é diferente entre viewbag e temptdata. O viewbag é baseado na primeira visualização (não compartilhada entre métodos de ação), mas os dados do temptd podem ser compartilhados entre um método de ação e apenas um outro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.