Tarefas básicas com Asp.MVC (CRUD)    

Olá pessoal!

Continuando os tópicos básicos do Asp.Net MVC, hoje vou fazer um pequeno cadastro para mostrar como interagir entre View e Controller. Vou procurar fazer tudo manualmente, para que você possa entender como funciona de fato essa intereção. Digo isso porque existem muitas formas de facilitar o desenvolvimento de Views, por exemplo, utilizando HTML Helpers, mas não vou fazer uso deles para que possamos, quando formos falar dos Helpers, entender como é o seu funcionamento.

Para nosso post hoje, vou criar apenas uma tabela no SQL Server Express para armazenar um cadastro de pessoas, como o objetivo é mostrar a Interação Controller/View/Controller, não vou tomar cuidado com validações, nem com um modelo elaborado.

Para começar, vamos criar nossa tabela como abaixo, e criar o acesso aos dados utilizando Entity Framework.

image

image

Feito isso, vamos adicionar um Controller no projeto chamado Cadastro, lembre-se que sempre começamos o desenvolvimento do site MVC adicionando o Controller. Coloquei “site” em negrito, porque muitos podem dizer que é pelo Modelo, ou Domínio, que se inicia o desenvolvimento, inclusive é o que prega as práticas de DDD (Domain Driven Development), mas quero deixar claro que o Modelo (Domínio) de fato é o princípio do desenvolvimento do Projeto, mas quando vamos iniciar o site, o Modelo já deve estar definido, portanto, conhecendo o Modelo você deve iniciar o site pelos Controllers necessários para esse Modelo, entendendo que o Modelo não é para o site, mas para o projeto, pois ele pode ser utilizado para qualquer ambiente. No futuro vou falar um pouco de DDD, visto que no MVC, a sua utilização é extremamente útil.

Adicionando o Controller, vamos marcar as opções para adicionar as Actions de Create, Update, Delete e Details, apenas para facilitar, visto que não é necessário utilizar exatamente métodos com esse nome para realizar o CRUD dos registros. Veja que ele criar algumas Actions com o mesmo nome, o motivo é bem simples:

Como para acessar uma View devemos acessar pela URL o Controller que contem a Action que sabe gerar essa View (por exemplo: http://seusite/Cadastro/Create), algumas Actions precisam se chamadas para renderizar a View e outras para Processar a requisição da View renderizadas anteriormente. Por exemplo: Para criar um novo registro, eu devo invocar a Action Create para renderizar os campos em brancos, dessa forma invocando a Action Create sem parâmetros, que só deve renderizar a View pura, e em seguida, após preencher os campos e clicar no botão Salvar, eu devo invocar a Action Create novamente, porém agora passando as informações que foram preenchidas, chamando dessa forma a Action com parâmetros. Isso é possível porque o motor do Asp.Net MVC consegue diferenciar overloads de métodos de acordo com as informações passadas no corpo da mensagem. Você precisa sempre utilizar essa regra de Overloads para Actions com funções ligadas? Não! No Asp.Net MVC você tem o controle de tudo, e pode usar da forma que achar melhor.

Além de criar as Actions do CRUD, ele também cria uma Action chamada Index, que é a invocada pelo Asp.Net se nenhuma Action form informada na URL. Precisa sempre ter o nome Index? Não! Como eu disse, você pode mudar quase qualquer coisa no MVC, apenas mudando as rotas padrões no arquivo Global.asax.

Abaixo segue todo o código do meu Controller. Você verá que cada método é muito simples:

  public ActionResult Index()
        {
            using (var bd = new bdEntities())
            {
            var query = from pessoas in bd.Pessoa select pessoas;

                //ObjectQuery p = new ObjectQuery("select cod_pessoa,nom_pessoa,des_email,num_telefone from  Pessoa", bd);
                //var resultado = p.Execute(MergeOption.NoTracking);

            
                return View(query.ToList());
            }
        }

      
        public ActionResult Create()
        {
            return View();
        } 

        [HttpPost]
        public ActionResult Create(FormCollection collection)
        {
            try
            {

                using (var bd = new bdEntities())
                {


                    var pessoa = new Pessoa();

                    pessoa.Email = collection["txtEmail"];
                    pessoa.Nome = collection["txtNome"];
                    pessoa.Telefone = collection["txtTelefone"];

                    bd.AddToPessoa(pessoa);
                    bd.SaveChanges();
                }


                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
        
        public ActionResult Edit(int id)
        {

            using (var bd = new bdEntities()){
                var pessoa = (from p in bd.Pessoa
                             where p.Codigo == id
                             select p).First();
                         
            return View(pessoa);
            }
        }

        [HttpPost]
        public ActionResult Edit(int id, FormCollection collection)
        {
            try
            {
                using (var bd = new bdEntities())
                {
                    var pessoa = (from p in bd.Pessoa
                             where p.Codigo == id
                             select p).First();

                    pessoa.Email = collection["txtEmail"];
                    pessoa.Nome = collection["txtNome"];
                    pessoa.Telefone = collection["txtTelefone"];

                    
                    bd.SaveChanges();
                }

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        public ActionResult Delete(int id)
        {
            using (var bd = new bdEntities())
            {
                var pessoa = (from p in bd.Pessoa
                              where p.Codigo == id
                              select p).First();

                bd.DeleteObject(pessoa);
                bd.SaveChanges();
                return RedirectToAction("Index");
            }
        }

Você pode excluir a Actions que não foram utilizadas, como Details (não teremos em nosso cadastro e Delete com dois parâmetros, pois o registro será excluído diretamente da lista.

Perceba que alguns trechos de códigos foram repetidos algumas vezes, e obviamente isso não é legal. Para solucionar esse problema, deveríamos criar um Domínio (Modelo) mais elaborado, encapsulando os métodos de pesquisas, mas para simplificar nosso modelo, resolvi fazer assim. Perceba também que alguns métodos recebem como parâmetro a classe FormCollection. Nesse parâmetro é armazenado todos os campos enviados a partir de formulários do HTML para o Controller, como era feito com Request.Form. É daí que leremos as informações fornecidas pelo usuário.

Você pode estar se perguntando: Posso colocar um método de auxilio no Controller, para facilitar a reutilização? A resposta é: não! Lembre que o MVC procura deixar claro o conceito de SoC - Separation of concerns (Separação de Interesses), por isso, todo método dentro de um Controller, tem a intenção de ser um Controlador (Action), e qualquer método (público) que você colocar ali dentro, será uma Action, mesmo que retorno um tipo incompreensivo para o Navagador. Tudo que tenha a ver com regra de negócio, deve ser colocado na camada Model.

Após criarmos nossos Controllers e Actions, vamos criar as Views.

Três actions necessitam ter Views específicas, são elas:

  • ActionResult Index()  - Retornará a lista de registros.
  • ActionResult Create()  - Retornará o formulário de criação de usuário.
  • ActionResult Edit(int id) – Retornará o formulário de edição de usuário já com os dados preechidos.

As demais Actions não precisam de View específica porque elas apenas persistem as informações e redirecionam o usuário para a listagem, criada na Action Index, sendo esse redirecionamento feito através do método RedirectToAction.

Para criar a View, clique no nome do método com o lado direito do método e Add View.

Vamos ver como ficará nossa View de listagem (Index)

    <h2>Lista de Pessoas</h2>
    <table>
		<thead>
			<tr>
				<th>Ação</th>
				<th>Nome</th>
				<th>E-mail</th>
				<th>Telefone</th>
			</tr>
		</thead>
		<tbody>
		<%foreach(var item in ViewData.Model){ %>
			<tr>
				<td><a href="Cadastro/Edit/<%=item.Codigo %>">Editar</a> <a href="Cadastro/Delete/<%=item.Codigo %>">Excluir</a></td>
				<td><%=item.Nome %></td>
				<td><%=item.Email%></td>
				<td><%=item.Telefone %></td>
			</tr>

		<%} %>
		</tbody>
    </table>
    <a href="Cadastro/Create">Novo</a>

Explicando: Estou criando uma tabela e fazendo um foreach no retorno da Action, que sempre fica exposto através da propriedade ViewData.Model. Para criar a coluna com os links de ação, perceba que estou adicionando links, e montando a URL de acordo com a estrutura Controller/Action/Parametros, e o botão para adicionar um novo, passando apenas Controller/Action. O resultado seria isso:

image

Para as duas outras Views, como vou submeter dados ao servidor, preciso criar um formulário, e definir como Action desse formulário, minha Action do Controller que receberá esses dados. Como são no mesmo Controller, posso apenas fornecer o nome da Action, sem passar o nome do Controller. A diferença de uma para outra é que uma eu já preencho os dados, e outra não:

View de Criação:

 <form name="formCadastro" action="Create" method="post">
    <h2>
        Criar novo Contato</h2>
    <p>
        <span>Nome</span><input type="text" name = "txtNome" id="txtNome" /></p>
    <p>
        <span>E-mail</span><input type="text" name = "txtEmail"  id="txtEmail" /></p>
    <p>
        <span>Telefone</span><input type="text" id="txtTelefone" name = "txtTelefone"  /></p>
    <p>
        <input type="submit" value="Salvar" /></p>
    </form>

View de Edição:

 <form name="formCadastro" action="Edit" method="post">
    <input type="hidden" id="hdfCodigo" name="id" value="<%=ViewData.Model.Codigo %>" />
    <h2>
        Alterar Contato</h2>
    <p>
        <span>Nome</span><input type="text" value="<%=ViewData.Model.Nome %>" name="txtNome"
            id="txtNome" /></p>
    <p>
        <span>E-mail</span><input type="text" value="<%=ViewData.Model.Email%>" name="txtEmail"
            id="txtEmail" /></p>
    <p>
        <span>Telefone</span><input type="text" id="txtTelefone" value="<%=ViewData.Model.Telefone %>"
            name="txtTelefone" /></p>
    <p>
        <input type="submit" value="Salvar" /></p>
    </form>

Diferente do WebForm no MVC você pode colocar quantos formulários quiser em uma mesma página, como é normal em qualquer outra plataforma Web, ou mesmo alterar o Action em tempo de execução. Para que as informações aparecem no parâmetro FormCollection, seus controles precisa ter o atributo name definido, pois é de onde o HTTP retira as informações para criar a mensagem (Post ou Get) a ser enviada ao server. No caso das Views acima, estou enviando via POST, como pode ser visto no atributo method do formulário.

Com esses códigos você já tem seu cadastro funcionando. Com certeza, para desenvolvê-lo você levará menos tempo que para ler esse post. Tudo ficou muito rápido e transparente, sem inúmeros arquivos de códigos inseridos pelo Asp.Net como acontece com o WebForm.

Como eu disse, não utilizei nenhum Helper do MVC para gerar HTML, se tivesse utilizado, com certeza o tempo gasto para desenvolver esse cadastro seria ainda menor.

Conclusão

Nesse post procurei mostrar como é simples criar uma página básica de cadastro. Nos próximos posts tentarei mostrar como deixar essa página um pouco mais elaborada.

Clique no arquivo abaixo para baixar o fonte do exemplo

MvcCrud.rar (426,09 kb)

Até o próximo

30. novembro 2010 14:36 by Frederico | Comments (1) | Permalink

Comments

Abdul Hade
Isso não um CRUD, CRUDS, tem campo de busca!
18/05/2012 05:12:57 #
Comments are closed

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  dezembro 2018  >>
seteququsedo
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET