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.