ASP.Net MVC – ViewData, ViewBag e TempData entenda as diferenças.
Quando usar ViewData, ViewBag e TempData? Essa é uma das primeiras perguntas que qualquer desenvolvedor faz quando inicia nos aprendizados do ASP.Net MVC.
UPDATE – 13/06 – Adicionando detalhes/correções fornecidos pelo @vcavalcante
Vamos basear nossa explicação conforme a ilustração
Similaridades entre ViewData e ViewBag
ViewData e ViewBag são similares nas seguintes características:
- São utilizadas para persistir dados entre a Controller e a View correspondente.
- A duração “tempo de vida” é apenas entre o envio através da Controller e a exibição na View, depois disso tornam-se nulas novamente.
- No caso de um redirect se tornam nulas.
Diferenças entre ViewData e ViewBag
ViewData | ViewBag |
É um dicionário de objetos derivado de ViewDataDictionary e é acessível utilizando strings como chaves. | É uma propriedade dinâmica baseada na funcionalidade “dynamic” do C# 4.0 |
Requer typecasting (conversão) quando associada a tipos complexos. | Não necessida de conversão para tipos complexos. |
Exemplos de aplicação
Controller
public class HomeController : Controller { public ActionResult Index() { // Meu dado de tipo complexo var func = new Funcionario { Nome = "Eduardo Pires", Idade = 31 }; // Propriedades "Dinâmicas" ViewBag.Funcionario = func; // Modo tradicional ViewData["Funcionario"] = func; return View(); } }
View
@model ProjetoModelo.Models.Funcionario; @{ ViewBag.Title = "Exemplo ViewData ViewBag"; // Necessita de TypeCasting var viewDataVariavel = ViewData["Funcionario"] as Funcionario; // Não necessita de TypeCasting var viewBagVariavel = ViewBag.Funcionario; }
Resumindo, ViewData e ViewBag possuem a mesma proposta, porém o ViewBag está disponível a partir do ASP.Net MVC 3, enquanto o ViewData existe desde a primeira versão.
OBS: O ViewData é um wrapper, uma implementação do ViewBag, pois utiliza o ViewBag internamente, portanto:
// Criar o ViewBag: ViewBag.Teste = "Eduardo"; // É o mesmo que criar um ViewData["Teste"], // pois o ViewData é utilizado internamente. Se chamarmos: var teste = ViewData["Teste"]; // Teremos teste = "Eduardo";
Por este motivo ViewData é mais rápido que o ViewBag, porém essa diferença de velocidade é mínima, não é necessário deixar de usar o ViewBag por este motivo.
Eu preferencialmente sempre utilizo ViewBag
TempData
- TempData assemelha-se mais a uma sessão de servidor, porém de curta duração.
- Possui um tempo de vida maior que o ViewBag e ViewData, o TempData perdura desde sua criação até que seja chamado, ou seja, quando houver um request da informação do TempData, ele se tornará nulo novamente.
- Uma informação em TempData criada em um Controller persiste após um redirect entre actions (apenas um) e pode ser exibido em sequência em uma View (muito usado em tratamento de erros).
- Caso não seja chamado o TempData pode manter o estado de seus dados até que a sessão do usuário se encerre.
- É utilizado para compartilhar informações entre Controllers.
- O TempData salva suas informações no SessionState do servidor.
- Após a leitura os dados do TempData são marcados para deleção, ou seja, no final do request todos os dados marcados serão deletados.
- É um benefício quando necessário transmitir um volume de informações entre as Controllers sem se preocupar em zerar os valores, pois o TempData automaticamente faz isso.
Exemplo de aplicação
Controller
public class HomeController : Controller { [HttpPost] public ActionResult CriarFuncionario(Candidato cd) { // Meu dado de tipo complexo var func = new Funcionario { Nome = cd.Nome, Idade = cd.Idade }; // Pertistir dados até o próximo request. TempData["Funcionario"] = func; // Redirect entre Controllers return RedirectToAction("CriarBeneficiosFuncionario"); } [HttpGet] public ActionResult CriarBeneficiosFuncionario() { // Validando se está vazio if (TempData["Funcionario"] != null) { // Necessário TypeCasting para tipos complexos. var func = TempData["Funcionario"] as Funcionario; } return View(); } }
Neste exemplo pudermos entender que o propósito do TempData é compartilhar dados entre Controllers, portanto sua duração persiste até que a informação seja lida.
Outro detalhe é sempre checar se o TempData não está nulo.
Caso você queira manter o dado de um TempData mesmo após a leitura, basta chamar o método Keep(), assim o dado será persistido novamente até a próxima requisição.
// Mantendo o dado do TempData até a próxima leitura (requisição). TempData.Keep("Funcionario"); // Removendo o dado do TempData desta e da próxima requisição. TempData.Remove("Funcionario");
Recomenda-se utilizar sempre ViewBag e ViewData para transferência de dados entre Controller e View. O TempData em Views é recomendado no caso de um dado necessitar ser redirecionado entre Actions e posteriormente ser exibido numa View (ViewBag e ViewData são anulados em redirects).
Um caso comum dessa aplicação é no tratamento de erros, veja aqui um exemplo.
Espero ter esclarecido as diferenças e características de ViewData, ViewBag e TempData. Caso tenha alguma dúvida ou queira comentar algo, deixe seu recado logo abaixo 😉
Referências
Eduardo, só acho que não ficou claro que o ViewBag na verdade é só um atalho para o ViewData, se criar um ViewBag.Funcionario = “Victor” e depois verificar o que contém no ViewData[“Funcionario”] irá perceber que o valor será “Victor”.
Neste post http://blog.lambda3.com.br/2012/01/debugando-sua-aplicacao-com-o-codigo-fonte-do-asp-net-mvc/ eu chego a falar sobre a implementação do ViewBag,
Abraços,
Legal Victor!
Não cheguei a ler seu post antes, mas com certeza é um dado importante para informar.
Vou dar uma lida, acredito que rola um update aqui 🙂
Muito obrigado pela contribuição.
Abraços!
Outra coisa, analisando o seu gráfico eu verifiquei que tem uma informação está faltando, você está demonstrando que tanto a ViewBag quanto a ViewData podem sair do Controller e ir para a View, mas não está demonstrando que o TempData também pode fazer isso.
Isso é muito utilizado para mensagens de erro por exemplo.
Eu criei um gist que exemplifica isso: https://gist.github.com/vcavalcante/5762825
Abraços,
Victor,
Propositalmente quis dar a entender que o TempData deve ser usado para troca de informação entre os Controllers.
No final do artigo comentei que o TempData não seria recomendado para troca de informação entre Controllers e Views, pois temos ViewBag e ViewData para isso.
No seu exemplo do gist você usou o TempData para informar um dado da Controller para a View, pois no caso do redirect na action anterior uma ViewBag ou ViewData teriam sido anulados.
Li o artigo da Rachel Appel (http://www.rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications) que também deixa claro o uso do TempData nas Views em um cenário igual o que você exemplificou.
Salvo o caso de um prévio redirect entre actions, Você poderia confirmar se existe alguma recomendação em não usar o TempData de Controllers para Views?
Mais uma vez obrigado pela colaboração.
Abraços!
Pela primeira vez vi uma explicação em português boa sobre essa assunto. Obrigado por compartilhar…
OBS: Se tiver tempo post mais coisas sobre a arquitetura MVC.
Olá Carlos,
Obrigado! Pode deixar, continue acompanhando, tenho vários assuntos engatilhados sobre MVC 4/5 para publicar 🙂
Abraços.
Excelente Eduardo, obrigado!!
Muito obrigado!
Abraços.
Otimo mesmo, todos seus artigos me ajudaram bastante até hoje.
Obrigado pelo feedback Rodrigo!
Abraços.
Excelente, obrigado
Muito obrigado!
Abraços.
Muito esclarecedor o artigo, parabéns.
Muito obrigado David!
Abraços.
Parabéns Eduardo! ficou bacana!
Show! Valeu.
Abs.
Excelente, ficou muito claro sim a diferença entre viewbag e viewdata!
Ótimo trabalho
Muito obrigado!!
Abs!!!
Eduardo, parabéns!
Você tem algum post ou exemplo de como fazer uma aplicação de pedido e item do pedido?
Não tenho Janderson,
Se sobrar tempo uma hora eu faço, mas tente ai e na dúvida me procure 🙂
Abs!!!
Excelente artigo, simples e objetivo !
Muito obrigado Luiz!
Abs!!!
Show de bola. Seu site tem muito conteúdo bacana pra .Net, vou guardar nos favoritos. Um abraço!
Obrigado pelo feedback Vinícius! Continue visitando 🙂
Abs!
Parabéns pelo artigo simples, porem muito explicativo e esclarecedor!
Fala Raphael!
Muito obrigado pelo feedback!
Abs!
Muito bom este artigo! Serviu para me ajudar a resolver um problemão aqui no projeto!!!
Parabéns e continue postando…rsrsrsrs…
Fala Jefferson!
Muito obrigado pelo feedback!
Abs!
Pingback: ASP.NET MVC – Acessar ViewBag de dentro da tag script | Wennder Santos
Muito bem explicado as diferenças entre ViewBag e ViewData neste artigo!
Obrigado pelo feedback Wesley.
Abraços.
Pingback: ASP.NET MVC – Acessando o conteúdo de um ViewBag de dentro da tag script | Wennder Santos
Pingback: Wennder Santos | Software development and other things.
Eduardo,
Parabéns pelos esclarecimentos.
Gostaria de fazer alguns questionamentos no uso destes recursos abordados no seu artigo.
Quando vou construir qualquer aplicação, gosto sempre de pesquisar melhores práticas adotadas em cada área, seja na arquitetura, usabilidade, etc. E para este assunto, encontrei que o uso de ViewBag e ViewData, em termos de melhores práticas, não era recomendável. A maioria dos artigos recomendam a criação de uma classe de transporte, como um ViewModel, para transacionar objetos e valores entre o Controller e a View. Queria saber o que você acha disso e ao mesmo tempo, saber qual a melhor estratégia para persistir valores de listas no mesmo contexto do Controller para todas as Actions disponíveis.
Também estou querendo saber a melhor estratégia para gravar valores de listas, por exemplo se as entidades tiverem relação one-to-many
Eduardo, você tem razão! Apesar de ser um bom recurso, não é uma boa prática utilizar desses artificios, uma vez que o MVC propõe um modelo a ser trabalhado na View.
Também não é rastreável os comportamentos devido os dados manipulados serem dinamicos.
Nos projetos grandes que participei criávamos TOs para transportá-los até a View.
Tendo em vista que as entidades não necessariamente precisavam ser subidas até a View.
tenho uma lista de Departamentos que trago da classe dalDepartamentos usando ADONET,
estou fazendo assim;
dalDepartamento daoDept = new dalDepartamento();
List<Departamento dept = daoDept.ListarDept();
ViewBag.Departametos = dept;
como retorno esta lista pra View
na view você faz um cast e pega
por ex
@{
List dept = (List)ViewBag.Departametos;
}
tirou as tags mas vc tem q transformar no mesmo tipo que você colocou na viewbag
Classe nome = (Classe)ViewBag.NomeViewBag
Bom dia,
Estou iniciando meus trabalhos com MVC, caso tenham algum artigo para iniciantes, por favor postem.
abraços
Faltou um exemplo do uso do TempData na view.
Boa noite,
Quero retornar para a view e estou fazendo assim:
14
Demandas na Qualidade
@{
var viewBagVariavel = ViewBag.retornoDemandas;
}
Demandas no Desenvolvimento
Não está funcionando, pode ajudar?
Grato pela atenção.
Joelso