Nenhum comentário


ASP.NET MVC – Parte II

 

Vimos na primeira parte desse artigo, uma base de como é a tecnologia ASP.NET MVC. Fizemos um comparativo com o Web Forms e iniciamos alguns exemplos. Nesse artigo, vamos nos aprofundar, trabalhando com banco de dados.

 

No ASP.NET MVC podemos trabalhar com LINQ e Entity framework. Podemos criar um banco do “zero”, utilizando nossos modelos (classes) ou podemos fazer engenharia reversa com um banco existente.

Entity Framework Power Tools

Fazer engenharia reversa (criar classes baseadas nos objetos do banco), não é algo simples. Imagine seu banco de dados com 50 tabelas, Stored Procedures e Functions? Seria muito trabalhoso fazer isso manualmente (criar classe por classe). Por isso, temos uma ferramenta que auxilia nessa tarefa e em muitos outros trabalhos, o Entity Framework Power Tools.

 

Acesse o link: http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d. Até o fechamento dessa edição, a ferramenta estava na versão Beta 4. As versões suportadas pelo Visual Studio são 2013, 2012 e 2010. Veja na Figura 1 o menu.

 

 

Figura 1. Menu do Entity Framework Power Tools

 

A ferramenta vai gerar todas as classes referente as tabelas do banco, assim como uma classe de contexto. Se você já usa o EF e tem um modelo (arquivo EDMX), é possível “transformar” esse modelo em classes (Code First).

Clique com o botão direito sobre o projeto e escolha o menu Entity Framework>Reverse Engineer Code First.

 

Será aberto o editor de configuração e conexão com o banco de dados. Coloque os parâmetros necessários para conectar ao banco de dados que deseja. A ferramenta cria as classes na pasta Models, como também a classe de contexto (Figura 2).

 

 

Figura 2. Exemplo de geração de classes usando engenharia reversa

Criando o banco de dados

Nesse exemplo, vamos criar uma aplicação do zero. Crie uma nova aplicação ASP.NET MVC e na pasta Models crie uma classe chamada “Pessoa”. Veja na Listagem 1 o código da classe Pessoa.

 

Listagem 1. Classe Pessoa

namespace EntityFirst.Models

{

    public class Pessoa

    {

        [Key]

        public int nCdPessoa { get; set; }

        public string sNmPessoa { get; set; }

        public DateTime tDtNascimento { get; set; }

        public double nVlLimite { get; set; }

    }

}

 

Classe bem simples. Temos que atentar, para a marcação do campo nCdPessoa. O campo é a chave, então, precisamos indicar a responsabilidade da mesma, para que o EF saiba como gerenciar esse modelo.

 

Vamos criar agora o contexto da aplicação. O contexto é o responsável por gerenciar os objetos e dados da aplicação, ele que faz o controle de alterações, preenche os objetos com dados e faz a persistência no banco.

 

Veja na Listagem 2 o contexto da nossa aplicação.

 

Listagem 2. Classe contexto

using System.Data.Entity;

...

 

namespace EntityFirst.Models

{

    public class ContextDB: DbContext

    {

        public DbSet<Pessoa> Pessoas { get; set; }

    }

}

 

Veja que herdamos de DbContext. A partir de agora, toda classe criada dentro de Models, precisa ser referenciada na classe ContextDB, para que possamos interagir com a mesma usando o contexto.

Scaffolding

Scaffolding é uma técnica para geração de templates automáticos, baseado em um modelo. No artigo anterior, desenvolvemos manualmente as Views de exemplos, inclusive do cadastro, bem como implementamos as Actions no Controller.

 

Mas você sabia que o Visual Studio pode criar tudo isso para você? Vamos criar um novo Controller e atente para o editor (Figura 3).

 

 

Figura 3. Editor de criação do Controller

 

Veja as opções no item Template. No exemplo anterior, escolhíamos a opção Empty MVC controller, ou seja, um controller vazio. Agora, escolha a segunda opção, que indica que vamos usar Entity Framework.

 

Em Data Context class, escolha a classe do contexto. Em Model class, escolha a classe Pessoa. Clique em Add.

 

Nota: caso a classe do contexto não apareça no item Data Context class, dê um build na aplicação e refaça o passo a passo.

 

Veja que foi criado o controller, assim como uma pasta Pessoa em View e alguns arquivos para o cadastro da pessoa (Figura 4).

 

 

Figura 4. Cadastro usando template do Visual Studio

 

Abra a classe PessoaController e note que todos os métodos são criados, assim como todas as páginas para um CRUD. Se precisarmos adaptar, basta mexer onde necessário. Execute a aplicação e faça um teste.

 

Nota: crie um controller chamado “Home” para direcionar ao cadastro ou altere o arquivo RouteConfig.cs para chamar o controller Pessoa no lugar de Home (padrão).

 

Cadastre, navegue e exclua registros (Figura 5).

 

 

Figura 5. Opções de cadastros criados pelo template

 

Se fecharmos a aplicação e rodarmos novamente, os dados continuam lá. Mas como, você pode se perguntar. Simples, o Entity Framework notou que não tínhamos uma base de dados, ele criou uma J.

 

Na segunda execução da aplicação, a base de dados existe, portanto, ele não precisou criar. Abra o arquivo Web.config e veja a string de conexão criada:

 

<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-EntityFirst-20131125201039;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-EntityFirst-20131125201039.mdf" providerName="System.Data.SqlClient" />

 

Abra o Management Studio e localize o banco de dados criado (Figura 6).

 

 

Figura 6. Banco de dados criado pelo Entity Framework

Como funciona?

Vamos entender como o Visual Studio criou as páginas, controller e actions. O arquivo Index.cshtml é o arquivo principal do cadastro de Pessoa. É nele que iniciamos, pois tem a lista com as pessoas cadastradas, assim como podemos editar, remover e adicionar novos registros.

 

Veja na Listagem 3 o código.

 

Listagem 3. Código do arquivo Index.cshtml

<h2>Index</h2>

 

<p>

    @Html.ActionLink("Create New", "Create")

</p>

<table>

    <tr>

        <th>

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

        </th>

        <th>

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

        </th>

        <th>

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

        </th>

        <th></th>

    </tr>

 

@foreach (var item in Model) {

    <tr>

        <td>

            @Html.DisplayFor(modelItem => item.sNmPessoa)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.tDtNascimento)

        </td>

        <td>

            @Html.DisplayFor(modelItem => item.nVlLimite)

        </td>

        <td>

            @Html.ActionLink("Edit", "Edit", new { id=item.nCdPessoa }) |

            @Html.ActionLink("Details", "Details", new { id=item.nCdPessoa }) |

            @Html.ActionLink("Delete", "Delete", new { id=item.nCdPessoa })

        </td>

    </tr>

}

 

</table>

 

O código é semelhante a Lista.cshtml, mostrada no artigo anterior. Gostaria que atentasse na parte final do código, onde temos três ActionLink. Um para edição, outro para visualizar o cadastro e o terceiro para excluir.

 

Note que no link, estamos passando um parâmetro, o código da Pessoa. Agora, veja na Listagem 4 o código do Edit no controller.

 

Listagem 4. Código do Edit do PessoaController

public ActionResult Edit(int id = 0)

{

  Pessoa pessoa = db.Pessoas.Find(id);

  if (pessoa == null)

  {

    return HttpNotFound();

  }

  return View(pessoa);

}

 

O código, recebe como parâmetro o código da pessoa, que visualizamos na ActionLink da Listagem 3. Assim, pesquisamos o objeto e retornamos para a View. Se não for encontrado, um erro será executado.

 

Temos outro método Edit no controller, mas esse se refere ao ato de editar (atualizar) o registro selecionado. Por isso, ele tem a marcação de ser um HttpPost e recebe como parâmetro um objeto Pessoa. Veja o código na Listagem 5.

 

Listagem 5. Código do Edit para atualizar os registros

[HttpPost]

[ValidateAntiForgeryToken]

public ActionResult Edit(Pessoa pessoa)

{

   if (ModelState.IsValid)

   {

      db.Entry(pessoa).State = EntityState.Modified;

      db.SaveChanges();

      return RedirectToAction("Index");

   }

   return View(pessoa);

}

 

Verificamos se os dados são válidos e atualizamos o mesmo usando o Entity Framework. Após, redirecionamos para a lista, usando RedirectionToAction.

 

Os métodos Delete são bastante semelhantes ao Edit, um apenas busca os dados para mostrar e solicitar a confirmação do usuário, enquanto o outro, efetiva a exclusão do objeto no banco. Os métodos Create, também não tem nada de diferente do que vimos.

 

Se fossemos criar nossos cadastros, sem a ajuda de scaffolding, poderíamos usar a mesma lógica e modificar o que for necessário, mas acredito que não mude muito do que foi visto.

 

Nota: deixo como dica a pesquisa a fundo dos arquivos CSHTML para ver como foi criado o cadastro, links etc.

Pesquisa

Estamos acostumados a usar filtragem de dados (pesquisa) para que o usuário da aplicação possa achar o registro que precisa. Vamos adaptar a lista, para que possamos realizar uma pesquisa pelo nome da pessoa.

 

Vamos modificar o método Index que retorna todos os registros de Pessoa do banco. Veja na Listagem 6 como deverá ficar o código (se quiser, comente o código atual e coloque esse novo).

 

Listagem 6. Adaptando o método Index para pesquisar

public ActionResult Index(string nome)

{

   var pessoas = db.Pessoas.ToList();

 

   if (!string.IsNullOrEmpty(nome))

   {

      pessoas = pessoas.Where(p =>

        p.sNmPessoa.ToUpper().Contains(nome.ToUpper())).ToList();

   }

           

   return View(pessoas);

}

 

Adicionamos um parâmetro ao método do valor digitado pelo usuário. Primeiramente, continuamos selecionando todos os registros de Pessoa. A seguir, verificamos se o parâmetro não é nulo ou vazio para que possamos pesquisar pelo nome da pessoa, usando o valor do parâmetro.

 

Por fim, chamamos a View passando a lista de pessoas, que foi filtrada ou não. Agora, precisamos modificar Index.cshtml. Veja na Listagem 7¸ o código da modificação, que deve ser colocado abaixo do link que remete ao cadastro (Create new).

 

Listagem 7. Modificando a View para a pesquisa

<p>

    @using (Html.BeginForm())

    {   

         <p>

             Descrição: @Html.TextBox("nome")

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

         </p>

    }

</p>

 

Colocamos um bloco BeginForm para podermos pegar a ação do botão. A seguir, temos um rótulo e uma caixa de texto. O parâmetro do TextFor é o nome, e esse nome tem que ser igual ao nome do parâmetro que colocamos no método. Lembre-se disso. Após, adicionamos um botão que fará a pesquisa.

 

Execute a aplicação e acesse a lista de registros. Veja a caixa de texto e o botão de pesquisa. Faça uma pesquisa para testar (Figura 7).

 

 

Figura 7. Pesquisando registros na lista

 

Caso deseje aumentar a caixa de texto, um dos parâmetros do TextFor, chamasse htmlAttributes. Nele, podemos adicionar código CSS. Veja no código a seguir, como ficaria a caixa de texto com largura de 350px.

 

@Html.TextBox("nome", "", new { style = "width:350px" })

 

O segundo parâmetro é o valor do TextFor, assim, quando quisermos que apareça um valor default, basta preencher o mesmo.

Layout

Você deve estar se perguntando se as aplicações ASP.NET MVC serão feias como os exemplos mostrados até aqui. Claro que não, use a sua imaginação, afinal você tem o controle total sobre o HTML gerado. É sua responsabilidade, usar CSS, HTML 5, jQuery UI, enfim tudo que for possível para melhorar a aparência da sua aplicação.

 

Em Web Forms, temos as Master Pages para reutilizarmos o layout sem precisar refazer em todas as páginas ASPX. No ASP.NET MVC temos algo parecido. O arquivo _Layout.cshtml, presente na pasta View>Shared possui o layout padrão da aplicação.

 

Veja na Listagem 8 o código da página.

 

Listagem 8. Código do arquivo _Layout.cshtml

<!DOCTYPE html>

<html>

<head>

    <meta charset="utf-8" />

    <meta name="viewport" content="width=device-width" />

    <title>@ViewBag.Title</title>

    @Styles.Render("~/Content/css")

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

</head>

<body>

    @RenderBody()

 

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

    @RenderSection("scripts", required: false)

</body>

</html>

 

No inicio, temos o título, usando o ViewBag. Renderizamos arquivos CSS e temos a seção body. RenderBody é onde as páginas que usam esse layout serão renderizadas. Assim, podemos trabalhar com um layout com menu, botões de navegação, rodapé que todas as páginas terão o visual colocado aqui.

 

Faça um teste, adicione o código da Listagem 9.

 

Listagem 9. Mudando o layout

...

<body>

    <header>

        <h1>Cabeçalho</h1>

    </header>

 

    @RenderBody()

 

    <footer>

        <h1>Rodapé</h1>

    </footer>

...

 

Adicionamos um cabeçalho e rodapé que será mostrado em todas as páginas da nossa aplicação. Rode e faça o teste. Use a imaginação para colocar um menu no header, botões de navegação, informações no rodapé, enfim, crie e invente (ou chame um designer que faça isso J).

jQuery UI

jQuery UI é uma biblioteca para ajudar a criação de interfaces ricas. Nesse exemplo, veremos como adicionar um DatePicker para o campo Nascimento no cadastro. Precisamos atualizar o jQuery UI para uma versão mais atual do calendário. Acesse o menu Tools>Library Package Manager>Manage Nuget Package for Solution. Lembre-se, vamos atualizar apenas a nossa solução.

 

Caso tenha outros projetos e deseja fazer a mesma funcionalidade, terá que atualizar cada solução. Acesse o item Online>nuget.org e digite “jQuery UI datepicker” (Figura 8).

 

 

Figura 8. Atualizando o jQuery UI da Solution

 

Clique em Install.

 

Nota: caso a versão do projeto seja a mais atualizada, uma mensagem indicando que não ouve atualização será mostrada.

 

Agora, precisamos modificar o campo tDtNascimento para que seja do tipo TextBoxFor e na seção Scripts do Create.cshtml modificar como na Listagem 10.

 

Listagem 10. Configurando o calendário

@section Scripts {

 

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

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

    @Styles.Render("~/Content/themes/base/css")

 

    <script>

        $(function () {

            $("#tDtNascimento").datepicker();

        });

    </script>

}

 

Execute a aplicação e veja o calendário quando posicionamos o mouse no campo (Figura 9).

 

 

Figura 9. Calendário no cadastro de pessoa

 

Podemos customizar o método datepicker de várias maneiras, inclusive traduzindo para o português as informações mostradas. Veja na Listagem 11 alguns parâmetros do datepicker.

 

Listagem 11. Customizando o calendário

$("#tDtNascimento").datepicker({

   dateFormat: 'dd/mm/yy',

   dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'],

   dayNamesMin: ['D','S','T','Q','Q','S','S','D'],

   dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb','Dom'],

   monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'],

   monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'],

   nextText: 'Próximo',

   prevText: 'Anterior',

   closeText: 'Fechar',

   currentText: 'Hoje'

});

 

Rode a aplicação e veja as modificações (algumas aparecem apenas de acordo com o tema usado na aplicação).

Popup

Janelas popups são muito utilizadas em aplicações Web. Seja para mostrar uma mensagem ou até mesmo ser usada como cadastro. Podemos usar o jQuery UI para criar janelas simples, modal e com animações.

 

No primeiro exemplo, basta colocar um div onde se deseja criar o popup e configurar o botão que vai chamar a janela. Veja no código da Listagem 12 o exemplo.

 

Listagem 12. Chamando uma janela popup

<div id="dialog" title="Popup simples">

  <p>Texto que será mostrado no popup.</p>

</div>

 

<button id="opener">Popup</button>

 

<script>

    $("#opener").click(function () {

        $("#dialog").dialog("open");

    });

 

    $(function () {

        $("#dialog").dialog({

            autoOpen: false

        });

    });

</script>

 

Nota: não esqueça de adicionar os scripts e estilos para o jQuery UI, semelhante ao mostrado no exemplo do datepicker, da Listagem 10.

 

Criamos um código para que ao clicar no botão seja chamado o popup, mostrando o texto colocado na div. Dentro do método dialog temos parâmetros de configuração e nesse exemplo, indicamos que o popup não será aberto automaticamente.

 

Veja a aplicação com janela de popup na Figura 10.

 

 

Figura 10. Janela de popup

 

Lembrando que você pode adicionar controles, rótulos, enfim o que quiser dentro do div que “representa” a janela popup. Mas se tivemos links, botões na página que chamou o popup e o usuário quiser clicar e isso quebra regras da aplicação?

 

Para que isso não ocorra, precisamos usar a opção modal no popup, assim, somente o que estiver no popup pode ser clicado. Para que nossa janela seja modal, basta adicionar o seguinte código dentro do método dialog:

 

modal: true

 

Simples. Faça um teste, execute a aplicação, chame o popup e tente clicar em algum link ou botão que esteja na página chamada.

 

Nota: Veja na página do jQuery UI (http://jqueryui.com/dialog) como colocar um efeito na abertura da janela popup.

 

Conclusões

Vimos neste artigo como trabalhar com o Entity Framework em aplicações ASP.NET MVC. Deixamos o Visual Studio, usando templates, criar as views e actions. Entendemos como funciona esses métodos para que possamos customizá-los.

 

Ainda conhecemos um pouco do jQuery UI, uma biblioteca poderosa para que possamos enriquecer nossas aplicações Web. Existem bibliotecas de terceiros, algumas free, que também ajudam e muito no desenvolvimento de aplicações ASP.NET MVC.

 

Para fins de aprendizado, fica um desafio: adaptar o cadastro de pessoa para que use um popup. Será que seus conhecidos já são suficientes? Um grande abraço a todos e até a próxima!