Nenhum comentário


ASP.NET MVC – Parte I

 

Você já deve ter ouvido falar de ASP.NET. É uma arquitetura Web para criar sites, portais, aplicações Web. Mas você sabe o que é ASP.NET MVC? Em termos gerais tem a mesma finalidade: criar sites, portais, aplicações Web etc, mas com um conceito diferente do ASP.NET “original” (também chamado Web Forms).

 

O ASP.NET MVC é baseado no padrão MVC (Model View Controller), criado pela Xerox nos anos 70. Nesse padrão, é feita uma separação de responsabilidades nas camadas da aplicação (modelo, visão e controlador). Neste artigo quero mostrar as características do ASP.NET MVC para o leitor que não conhece, assim como mostrar dicas para desenvolvedores que já usam a arquitetura.

MVC x WebForms

Como sempre, temos um comparativo sobre características do Web Forms e MVC.

  • Web Forms: presente desde 2001, sendo o primeiro modelo de desenvolvimento do .NET e o mais utilizado atualmente. Tornou ágil o desenvolvimento de aplicações Web, usando o conceito “drag and drop” (arrastar e soltar).

Possui grandes opções de controles de tela, onde o HTML e funções JavaScript são criadas “sozinhas”. Entres os contras dessa arquitetura podemos destacar: pouco controle sobre o HTML e JavaScript gerado, impossibilidade de testes de interface, difícil integração com frameworks de JavaScript.

 

·         MVC: padrão de desenvolvimento MVC, faz a separação de responsabilidades das camadas da aplicação, controle total sobre o HTML e JavaScript gerado, podemos criar testes de interface, etc. Entre os pontos negativos: não é RAD, não tem controles prontos, necessidade de aprendizado (modelo totalmente diferente do Web Forms), desenvolvimento maior de código.

 

O que as duas arquiteturas tem em comum? Rodam sobre o mesmo runtime (ASP.NET), geram páginas ASPX, rodam no IIS, tem o mesmo acesso a dados (LINQ, ADO.NET, Entity Framework) e desenvolvidos utilizando o Visual Studio. Ou seja, sua aplicação Web Forms, ao ser “convertida” para MVC, vai rodar normalmente no servidor.

Primeiro projeto

Após essa pequena explanação, vamos entender como funciona o ASP.NET MVC na prática. Criaremos exemplos usando o Visual Studio 2012 e a versão ASP.NET MVC 4. Os exemplos também podem ser feitos no Visual Studio 2010 (você deve instalar a versão 4 do ASP.NET MVC em separado).

 

No Visual Studio 2013, já temos a versão ASP.NET MVC 5. Crie um novo projeto ASP.NET MVC 4 Web Application no Visual Studio 2012 (Figura 1).

 

 

Figura 1. Criando um projeto ASP.NET MVC no Visual Studio 2012

 

Após, será aberto um editor onde escolheremos o template de projeto que podemos criar (Figura 2):

·         Empty: projeto vazio (sem scripts, arquivos de imagens etc);

·         Basic: projeto onde temos o básico da estrutura de pastas de um projeto ASP.NET MVC;

·         Internet Application: cria um projeto com autenticação usando Forms Authentication;

·         Intranet Application: cria um projeto com autenticação usando Windows Authentication;

·         Mobile Application: cria um projeto para aplicações mobile;

·         Web API: cria um projeto API para expor métodos onde outros sites irão consumir.

 

 

 

Figura 2. Escolhendo o template de projeto ASP.NET MVC

 

Como podemos ver na Figura 2, temos mais templates disponíveis, de acordo com a instalação de plug-ins e frameworks de terceiros. Em View Engine escolha Razor.

View engine é o responsável pela criação do HTML. Temos dois tipos: Razor e ASPX. Razor é mais enxuta e praticamente é C#, já o ASPX, usa tags de scripts para a criação do HTML. Veja na Listagem 1, exemplos de Razor e ASPX.

 

Listagem 1. Diferenças entre Razor e ASPX

Razor

@{

  string nome = "Luciano Pimenta";

  int numero = 0;

}

 

ASPX

<%

  string nome = "Luciano Pimenta";

  int numero = 0;

%>

 

No decorrer do artigo, veremos como funciona a engine Razor. Vamos escolher o template Basic para que possamos ter a estrutura básica de uma aplicação ASP.NET MVC.

Model View Controller

Na Figura 3 temos a estrutura da nossa aplicação.

 

 

Figura 3. Estrutura de uma aplicação basic para o ASP.NET MVC

 

Semelhante a uma aplicação ASP.NET Web Forms, temos várias pastas, mas temos três que são essenciais: Models, Views e Controllers. Na pasta Views temos as páginas (com extensão cshtml). Já em Controllers teremos as classes responsáveis pelas regras de negócios e em Models temos as classes de mapeamento do banco de dados.

 

Vamos entender um pouco sobre MVC. O padrão MVC foi criado pela Xerox em meados dos anos 70 e tem como principal caraterísticas separar as responsabilidades das camadas da aplicação. Temos um exemplo simples de como funciona o padrão na Figura 4.

 

 

Figura 4. Conhecendo o padrão de projeto MVC. Fonte: www.oficinadanet.com.br

 

O Model é responsável por “pegar” os dados do banco e disponibilizar para o Controller. Este por sua vez, “envia” os dados para a View e recebe novamente, repassando para o Model. O Controller também é responsável pela validação dos dados antes de enviar ao Model.

 

A View recebe os dados do Controller e exibe em tela, devolvendo para o Controller os dados alterados ou inseridos quando assim for solicitado. Veja que as responsabilidades são claras, não veremos em projeto ASP.NET MVC, código em páginas ASPX com comandos SQL no banco de dados, por exemplo.

 

Nota: isso não é correto nem em aplicação ASP.NET Web Forms, mas as primeiras aplicações tinham resquícios do ASP3.

 

Assim, sabemos que validações dos dados devem ser feitas no Controller, deixando a View com a responsabilidade de apenas exibir os mesmos. Como primeiro exemplo, vamos aprender como passar dados do Controller para a View, algo bastante comum no ASP.NET MVC.

Para aprender isso, precisamos primeiro entender como o Controller trabalha com a View.

Rotas

No ASP.NET MVC temos o conceito de rotas usando o ASP.NET Routing para rotear URLs. Uma rota indica: um Controller, uma Action e um parâmetro (opcional). Não temos mais URLs, como: localhost/NomeProjeto/Index.aspx ou localhost/NomeProjeto/Index.aspx?codigo=1. Agora teremos: localhost/NomeProjeto/Index ou localhost/NomeProjeto/Index/1.

 

Podemos dizer que a URL ficou mais amigável e mais fácil de compreensão. Index é a rota padrão de uma aplicação ASP.NET MVC. Todo Controller deve ter um método chamado Index (customizações são permitidas).

 

No arquivo RouteConfig.cs na pasta App_Start podemos ver o mapeamento da rota (Listagem 2).

 

Listagem 2. Mapeamento de rotas no RouteConfig

public static void RegisterRoutes(RouteCollection routes)

{

  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

  routes.MapRoute(

    name: "Default",

    url: "{controller}/{action}/{id}",

    defaults: new { controller = "Home", action = "Index",

      id = UrlParameter.Optional }

  );

}

 

O RegisterRoutes é chamado apartir do Application_Start do Global.asax.cs.

Trafegando dados entre Controller e View

Quando precisamos passar dados (independente se sejam oriundos de banco de dados ou não), podemos usar o ViewBag ou ViewData. ViewData podemos comparar com uma variável de sessão (objeto Session) do ASP.NET.

 

Podemos preencher no Controller e recuperar seu valor na View. Já o ViewBag é um objeto bem mais robusto onde podemos criar propriedades dinâmicas. Ou seja, podemos indicar o valor que queremos atribuindo a uma propriedade e na View apenas referenciar essa propriedade. Vamos a um exemplo.

 

No projeto criado, clique com o botão direito na pasta Controllers e escolha Add>Controller. No editor (Figura 5), vamos dar o nome de “HomeController”.

 

 

Figura 5. Criando um controller

 

Todo Controller criado já possui um método Index. No mesmo, temos o retorno da View. Altere o Index padrão para o seguinte código:

 

ViewData["HelloWorld"] = "Hello World";

ViewBag.Hello = "Hello";

ViewBag.World = "World";

 

Atribuímos para ViewData, de nome Hello, um valor. Na ViewBag, criamos duas propriedades dinâmicas e preenchemos. Esses valores serão apresentados na View. Clique com o botão direito na pasta Views e escolha Add>New Folder. Dê o nome de “Home”. Padronizamos que as pastas dentro de Views devem ter o mesmo nome dos Controllers.

 

Dentro da pasta Home, adicione uma View, clicando de direito e escolhendo Add>View. No editor (Figura 6), vamos dar um nome para a View: “Index”.

 

 

Figura 6. Criando uma view

 

Ao criar a View, temos um arquivo cshtml (como se fosse um ASPX), onde vamos codificar nossa página. Nela temos controle total do HTML, JavaSricpt, etc. Altere o código para o da Listagem 3.

 

Listagem 3. Codificando a View

@{

    ViewBag.Title = "Minha página Index";

}

 

<p>ViewData: <b>@ViewData["HelloWorld"]</b></p>

<p>Hello: <b>@ViewBag.Hello</b></p>

<p>World: <b>@ViewBag.World</b></p>

 

Note que usamos o caracter @ para invocar objetos na página. O Intelissense não funciona no ViewBag, por que as propriedades são dinâmicas. Execute a aplicação e veja o resultado (Figura 7).

 

 

Figura 7. Executando a aplicação

 

Mas e dados ou objetos, como fazer. Também é bastante simples. Vamos criar um Model. Clique com o botão direito na pasta Models e escolha Add>Class. Dê o nome de “Pessoa.cs” para a nova classe e adicione as seguintes propriedades:

 

public int PessoaID { get; set; }

public string Nome { get; set; }

public DateTime Nascimento { get; set; }

 

As classes da pasta Models, servem para mapear objetos do banco ou simplesmente ser um repositório. Vamos modificar o método Index do Home para o código da Listagem 4.

 

Listagem 4. Passando dados para a View

Pessoa pessoa = new Pessoa

{

   PessoaID = 1,

   Nome = "Luciano Pimenta",

   Nascimento = DateTime.Now

};

  

return View(pessoa);

 

O código é simples. Instanciamos uma classe Pessoa e repassamos esse objeto para a View. Agora, precisamos receber esse objeto na View. Veja a Listagem 5 para ver como foi modificada a View.

 

Listagem 5. Recebendo um objeto Pessoa na View

@model HelloWorld.Models.Pessoa

 

@{

    ViewBag.Title = "Minha página Index";

}

 

<p><b>Id</b>: @Model.PessoaID</p>

<p><b>Nome</b>: @Model.Nome</p>

<p><b>Nascimento</b>: @Model.Nascimento</p>

 

A primeira linha é importantíssima, pois nela indicamos qual model esta sendo recebido pela página. Com a indicação do tipo de objeto, usamos o @Model para trabalhar com o objeto recebido pela página, assim, podemos exibir suas propriedades onde desejarmos. Teste a aplicação.

 

Nota: veja que para indicarmos o objeto que a página recebe usamos o nome model em minúsculo. Para acessar as propriedades do objeto, usamos em maiúsculo.

 

E se estivéssemos trabalhando com mais de um objeto (uma consulta que retorna vários registros)? Como faríamos? Primeiro, vamos criar um novo método no Controller, chamado “Lista” e retornar vários objetos pessoas em uma lista. Veja na Listagem 6 o método Lista.

 

Listagem 6. Método Lista do HomeController

public ActionResult Lista()

{

   Pessoa pessoa1 = new Pessoa

   {

     PessoaID = 1,

     Nome = "Luciano Pimenta",

     Nascimento = new DateTime(1976, 5, 8)

   };

 

   Pessoa pessoa2 = new Pessoa

   {

     PessoaID = 2,

     Nome = "Alessandra Pimenta",

     Nascimento = new DateTime(1980, 6, 9)

   };

 

   Pessoa pessoa3 = new Pessoa

   {

     PessoaID = 3,

     Nome = "Luciano Castro",

     Nascimento = new DateTime(1978, 7, 22)

   };

 

   List<Pessoa> lista = new List<Pessoa>();

   lista.Add(pessoa1);

   lista.Add(pessoa2);

   lista.Add(pessoa3);

 

   return View(lista);

}

 

Apenas criamos alguns objetos Pessoa e colocamos em uma lista, que é repassada para a View. Crie uma nova View, na pasta Home, dando o nome de “Lista”. Na View, vamos adicionar o código da Listagem 7.

 

Listagem 7. View que receberá a Lista de Pessoa

@model List<HelloWorld.Models.Pessoa>

 

@{

    ViewBag.Title = "Lista";

}

 

<h2>Lista</h2>

 

<table>

    <tr>

        <th>Id</th>

        <th>Nome</th>

        <th>Nascimento</th>

    </tr>

    @foreach (var item in @Model)

    {

        <tr>

            <td>@item.PessoaID</td>

            <td>@item.Nome</td>

            <td>@item.Nascimento.ToString("dd/MM/yyyy")</td>

        </tr>

    }

</table>

 

Note, que você desenvolvedor é o responsável por exibir os dados na página. Não temos um Grid (componentes de terceiros nos auxiliam). A criação do HTML esta tudo em suas mãos. Agora, não estamos recebendo apenas um objeto Pessoa, mas sim um List<Pessoa>.

 

Criamos uma tabela com os cabeçalhos e usamos um foreach para percorrer a lista e exibir os dados. Para que possamos acessar a página da lista, precisamos criar um link. Em Index, adicione o seguinte código (abaixo do código do exemplo do Index):

 

@Html.ActionLink("Lista", "Lista", "Home")

 

ActionLink ira redirecionar para a View que queremos. O primeiro parâmetro indica o texto do link. O segundo a Action que iremos usar e no terceiro, será a rota. Execute a aplicação e veja o resultado (Figura 8).

 

 

Figura 8. Lista de pessoas da aplicação

Cadastro

Precisamos criar um cadastro. Vamos cadastrar uma pessoa e mostrar os dados inseridos pelo usuário. Ainda não usaremos banco de dados, mas a adaptação como veremos no próximo artigo, será muito simples. Veja o código da Action na Listagem 8.

 

Listagem 8. Métodos de cadastro

[HttpPost]

public ActionResult Create(Pessoa pessoa)

{

return View("ExibeDados", pessoa);

}

 

[HttpGet]

public ActionResult Create()

{

return View();

}

 

A ideia é receber o objeto Pessoa como parâmetro e repassar para o Index. Em uma aplicação real, iriamos inserir pessoa no banco de dados e depois redirecionar para onde quisermos.

 

O ASP.NET MVC é capaz de montar objetos com os valores dos parâmetros HTTP e passá-los como argumento para as ações dos controladores (por isso usamos a marcação HttpPost no Create). Note que no objeto View, temos alguns parâmetros, entre eles, de indicar o nome da View e o model que queremos passar.

 

Crie uma View chamada “Create”, e uso o código da Listagem 9.

 

Listagem 9. View para cadastro da pessoa

@model HelloWorld.Models.Pessoa

 

@{

    ViewBag.Title = "Cadastro";

}

 

<h2>Cadastro</h2>

 

@using (Html.BeginForm())

{ 

<fieldset>

    <legend>Cadastro</legend>

    <div class="display-label">

        @Html.DisplayNameFor(model => model.PessoaID)

    </div >

    <div class="display-field">

        @Html.EditorFor(model => model.PessoaID)

    </div >

    <div class="display-label">

        @Html.DisplayNameFor(model => model.Nome)

    </div >

    <div class="display-field">

        @Html.EditorFor(model => model.Nome)

    </div >

    <div class="display-label">

        @Html.DisplayNameFor(model => model.Nascimento)

    </div >

    <div class="display-field">

        @Html.EditorFor(model => model.Nascimento)

    </div >

</fieldset>

 

    <p>

        <input type="submit" value="Cadastro" />

    </p>

}

 

Como sabemos que teremos um objeto Pessoa na página, usamos @Html.EditorFor para montar uma caixa de texto e @Html.DisplayNameFor para exibir um rótulo.

 

Nota: No model, podemos marcar a propriedade para exibir o rótulo que quisermos, por exemplo usando a marcação:

[Display(Name = "Código da pessoa")]

public int PessoaID { get; set; }

 

Crie uma View chamada “ExibeDados” e implemente, semelhante ao Index, onde recebemos um model Pessoa, somente para exibição. Adicione um link no Index para ser direcionado ao cadastro criado anteriormente. Rode a aplicação e faça o teste.

Validações

No ASP.NET Web Forms, temos controles para validações, os Validators. Vou mostrar um exemplo, onde podemos validar os dados na Action do controller. Veja na Listagem 10, como fazer essa validação (método Create).

 

Listagem 10. Validando dados na Action do Controller

if (pessoa.PessoaID == 0)

   ModelState.AddModelError("PessoaID",

     "Campo PessoaID: preenchimento obrigatório.");

 

if (string.IsNullOrEmpty(pessoa.Nome))

   ModelState.AddModelError("Nome", "Campo Nome: preenchimento obrigatório.");

 

if (pessoa.Nascimento == null)

   ModelState.AddModelError("Nascimento",

     "Campo Nascimento: preenchimento obrigatório.");

           

if (ModelState.IsValid)

   return View("ExibeDados", pessoa);

 

return View();

 

Note que verificamos cada campo do objeto Pessoa (o que pode ser trabalhoso, dependendo da quantidade de campos validados). Quando a regra é quebrada, adicionamos a mensagem de erro no ModelState.

 

Na View, precisamos ainda fazer uma última modificação. Abaixo de cada controle de tela (EditorFor), precisamos colocar a indicação da validação do campo. Adicione o seguinte código (alterando o nome do campo para os demais):

 

@Html.ValidationMessageFor(model => model.PessoaID)

 

Na parte inferior da página (após o código HTML), vamos indicar a biblioteca jQuery que auxilia na exibição das validações:

 

@section Scripts{

    @Scripts.Render("~/bundles/jqueryval")

}

 

Rode e teste a aplicação. Agora, vamos conhecer uma maneira bem mais simples de validação, o DataAnnotations. Simplesmente, criamos uma marcação na propriedade do model, indicando o que queremos validar. Veja na Listagem 11 algumas validações de Pessoa.

 

Listagem 11. Validações com DataAnnotations

[Required(ErrorMessage="Campo PessoaID: preenchimento obrigatório")]

[Display(Name="Código da pessoa")]

public int PessoaID { get; set; }

 

[Required(ErrorMessage = "Campo Nome: preenchimento obrigatório")]

[StringLength(10, ErrorMessage="Campo Nome: máximo de 10 caracteres.")]

public string Nome { get; set; }

 

[Required(ErrorMessage = "Campo Nascimento: preenchimento obrigatório")]       

public DateTime Nascimento { get; set; }

 

Note que além da obrigatoriedade dos campos, adicionamos uma validação onde o campo Nome, deve conter até 10 caracteres. Fica mais fácil marcar a propriedade com DataAnnotations, do que comparar cada campo no Controller.

 

Rode a aplicação e tente cadastrar um registro com o nome em branco ou que a quantidade de caracteres do Nome seja maior que 10 (Figura 9).

 

 

Figura 9. Validações no ASP.NET MVC

Conclusões

Vimos neste artigo os primeiros passos para desenvolver projetos Web usando o ASP.NET MVC. No próximo artigo, veremos mais dicas e como trabalhar com banco de dados usando o Entity Framework. Um grande abraço a todos e até a próxima!