Passar dados dos controladores para as vistas

Neste artigo vamos ver como passar dados dos controladores para as exibições.

Por Eduard Tomás - Tradução CRV


Publicado em: 10/8/11
Valorize este artigo:
Há três métodos (que na verdade são dois) principais para passar dados dos controladores para as exibições.

Lembrem-se que segundo o padrão MVC, o controlador é quem acessa o modelo para obter os dados e mandá-los para a exibição. A exibição deve limitar-se a mostrar esses dados (ou a pedir dados novos e mandá-los de volta ao controlador, o que veremos mais adiante). Os dados que o modelo proporciona ao controlador podem vir de qualquer fonte (usualmente de uma base de dados).

Primeiro método: ViewData

O primeiro dos métodos é o denominado ViewData. ViewData é um dicionário de chave (uma cadeia) - valor (um objeto) que o controlador passa para a exibição. Um exemplo de uso de ViewData é o seguinte controlador:

public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Nome"] = "Eduard Tomàs";
ViewData["Twitter"] = "eiximenis";
return View();
}

}

Aqui se define o controlador Home com a ação Index (lembrem que as ações são os métodos públicos que recebem as requisições do navegador). Nesta ação estabelecemos as chaves Nome e Twitter do ViewData e em seguida devolvemos a exibição associada a tal ação.

Para mostrar os dados na exibição, simplesmente usamos a propriedade ViewData que têm as exibições e que funciona exatamente igual. Neste caso, no código de nossa exibição (arquivo Home.cshtml que estaria na pasta Home dentro da pasta Views) teríamos algo como:

<h2>Index</h2>

Meu nome é @ViewData["Nome"] e você pode me seguir em
<a href="http://twitter.com/@ViewData["Twitter"]">Twitter</a>.

Observem duas coisas:

  1. Para acessar um valor do ViewData, simplesmente usamos ViewData["chave"].
  2. E muito importante: o uso da arroba (@) antes de chamar ViewData. Isso faz parte da sintaxe Razor (que veremos com detalhes mais adiante, assim que de momento não nos vamos preocupar muito com ela).
O uso de ViewData tem dois pontos fracos que devemos ter presentes:
  1. As chaves são cadeias, de modo que se nos equivocarmos o compilador não nos pode ajudar. Tampouco ferramentas de refactoring podem nos dar suporte.
  2. ViewData["chave"] sempre devolve um object razão pela qual devemos ir fazendo casting se quisermos obter o tipo real do que há armazenado.
P.ex. Em um controlador colocamos o seguinte valor em ViewData:

ViewData["DataRegistro"] = new DateTime(2008, 12, 10);

Este valor é um DateTime, não obstante, se desde a exibição queremos chamar os métodos de DateTime (como ToLongDateString()) deveremos fazer um casting:

Registrado em: @(((DateTime)ViewData["DataRegistro"]).ToLongDateString())

Se não fizéssemos o casting para DateTime, a chamada a ToLongDateString() geraria uma exceção (ainda quando, de verdade, o que haja no ViewData["DataRegistro"] seja um DateTime).

Segundo método: ViewBag

ViewBag funciona de forma muito parecida a ViewData. Igual que ViewData, ViewBag é um dicionário de chave – valor, porém, se aproveita das capacidades de programação dinâmica que oferece C# 4, para em lugar de usar cadeias para especificar a chave, usar propriedades. Assim, desde uma ação podemos fazer:

public ActionResult Index2()
{
ViewBag.Nome = "Eduard Tomàs";
ViewBag.Twitter = "eiximenis";
ViewBag.DataRegistro = new DateTime(2008, 12, 10);
return View();
}

Observem que o código é quase igual ao uso de ViewData, só que em lugar de fazer ViewData["chave"] fazemos ViewBag.chave.

E para recuperá-los desde uma exibição? Pois igual que antes, podemos usar a propriedade ViewBag:

<h2>Index2</h2>

Meu nome é @ViewBag.Nome e você pode me seguir em
<a href="http://twitter.com/@ViewBag.Twitter">Twitter</a>. <br />
Registrado em: @ViewBag.DataRegistro.ToLongDateString()

Aqui podemos ver a grande vantagem de ViewBag com respeito a ViewData: não é necessário usar casting. Observem que para usar ToLongDateString() não tivemos necessidade de converter o resultado devolvido por ViewBag.DataRegistro para DateTime. Essa é a grande vantagem de ViewBag com relaçaõ a ViewData e é por isso que, pessoalmente, recomendo que vocês usem ViewBag em lugar de ViewData (na verdade ViewData se mantém por compatibilidade com as versões anteriores do framework de ASP.NET MVC). Outra vantagem é que não usamos cadeias mas sim propriedades para acessar os elementos, porém cuidado , porque o compilador não pode nos ajudar se acessarmos uma chave (propriedade) que não existe (ao serem as propriedades dinâmicas).

Terceiro método: Model (também conhecido como ViewModel)

O terceiro método para passar informação de uma ação de um controlador para uma exibição, é usando a propriedade Model. A propriedade Model não funciona como as anteriores; o que é passado é um objeto, que se envia da ação para a exibição.

À diferença de ViewData e ViewBag que existem tanto no controlador como na exibição, o controlador não tem uma propriedade Model. Em seu lugar se usa uma sobrecarga do método View() e se envia o objeto como parâmetro:

public class Usuario
{
public string Nome { get; set; }
public string Twitter { get; set; }
public DateTime Registro { get; set; }
}

public class HomeController : Controller
{
public ActionResult Index3()
{
Usuario data = new Usuario();
data.Nome = "Eduard Tomàs";
data.Twitter = "eiximenis";
data.Registro = new DateTime(2008, 12, 10);
return View(data);
}
}

Notemos as diferenças: O controlador cria um objeto da classe Usuario e manda esse objeto para a exibição, passando-o como parâmetro à função View.

E desde a exibição? Bem, usamos a propriedade Model para acessar tal objeto:

@model MvcHelloWorld.Controllers.Usuario

<h2>Index3</h2>
Meu nome é @Model.Nome e você pode me seguir em
<a href="http://twitter.com/@Model.Twitter">Twitter</a>. <br />
Registrado em: @Model.Registro.ToLongDateString()

Observem que agora usamos Model para acessar aos dados, em lugar de ViewData ou ViewBag. E uma coisa importante: observemos na primeira linha, que começa com @model. Essa linha indica ao framework de que tipo é o objeto que a exibição recebe do controlador (ou seja, de que tipo é a propriedade Model). Obviamente este tipo deve coincidir com o objeto passado como parâmetro à função View na ação do controlador. Uma observação: O uso de @model é opcional. Se não o colocarmos, nossa exibição pode seguir usando a propriedade Model, mas neste caso é de tipo dynamic. Isso tem suas vantagens e seus inconvenientes (voltaremos a ele em artigos posteriores). As exibições que declaram @model, são chamadas exibições fortemente tipadas. Usar exibições fortemente tipadas tem uma vantagem porque o fato de Visual Studio saber o tipo da propriedade Model, pode - nos proporcionar suporte de Intellisense.

Usar este mecanismo é a maneira preferida de passar dados desde uma ação para uma exibição (já que em lugar de ter dados dispersos em n chaves podemos tê-los organizados em uma classe). As classes passadas das ações para as exibições (como nossa classe Usuario) são conhecidas também com o nome de ViewModels (para distingui-las das classes que conformam o Modelo do padrão MVC, já que os ViewModels o único que fazem é conter dados que mostrará uma exibição).

Uma nota final

No começo do artigo comentei que veríamos três métodos que na realidade eram dois. A que me referia? Pois, basicamente a que ViewBag e ViewData são duas maneiras diferentes de acessar o mesmo conjunto de dados. Ou seja, se estabelecemos o valor de ViewData["Nome"] podemos lê-lo com ViewBag.Nome e viceversa. Daí que tenha comentado que eram três métodos, que realmente eram dois. Para mais informação recomendo o artigo de José M. Aguilar sobre o tema, que vocês podem ler em: http://www.variablenotfound.com/2010/12/viewbag-en-aspnet-mvc-3.html

Um abraço a todos!
PD: Só para comentar que o código fonte de todos os artigos desta série sobre ASP.NET MVC pode ser encontrado em: http://cid-6521c259e9b1bec6.office.live.com/browse.aspx/desarrolloweb-aspnetmvc





Comentários do artigo
Foi enviado 1 comentário ao artigo
1 comentário não revisado
0 comentários revisados

Usuários :    login / registro

Manuais relacionados
Categorias relacionadas
O autor

Home | Sobre nós | Copyright | Anuncie | Entrar em contato