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).
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:
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).
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).
À 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).
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