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