Olá pessoal!
Hoje vou fazer um post bem pequeno, mas que é uma resposta a uma pergunta deve surgir na cabeça de todo mundo que começa em MVC. Já tive essa dúvida no passado, já ouvi essa pergunta em WebCasts e me fizeram ela semana passada: Para cada Action eu devo ter uma View, mesmo que o formulário seja igual?
Mesmo no meu post de CRUD eu fiz assim, criei uma View para a Action Create e outra para a Action Edit, mas a idéia era realmente possibilitar a evolução do projeto, como fiz aqui e aqui, e agora nesse atual vou continuar aprimorando aquele projeto.
Nesse post vou mostrar que isso não é necessário, e em uma aplicação de verdade deve ser evitado, afinal programar repetidas vezes as mesmas regras de validação sempre é um risco para a manutenção.
Vamos ao código!
Primeiramente, excluí as Action Create, e sua respectiva View, para ser utilizada apenas a Action e View Edit. Vou inicialmente mostrar como ficou o código da View. Como agora não necessariamente ao carregar a View eu terei os dados para preencher os campos, devo fazer um preenchimento condicional, da seguinte forma:
<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>
Perceba que estou utilizando o operador ??, que verificar se o valor à esquerda é nulo e se for, utiliza o da direita. Na View, toda a alteração necessária é essa.
Nas minhas Actions fiz as seguintes mudanças:
1: public ActionResult Edit(int? id)
2: {
3: if (!id.HasValue) return View(new Pessoa());
4:
5: using (var bd = new bdEntities())
6: {
7: var pessoa = (from p in bd.Pessoa
8: where p.Codigo == id
9: select p).First();
10:
11: return View(pessoa);
12: }
13: }
14:
15: [HttpPost]
16: public ActionResult Edit(int id, FormCollection collection)
17: {
18: try
19: {
20: using (var bd = new bdEntities())
21: {
22: if (id ==0)
23: {
24: var pessoa = new Pessoa();
25: pessoa.Email = collection["txtEmail"];
26: pessoa.Nome = collection["txtNome"];
27: pessoa.Telefone = collection["txtTelefone"];
28: bd.AddToPessoa(pessoa);
29: bd.SaveChanges();
30: }
31: else
32: {
33: var pessoa = (from p in bd.Pessoa
34: where p.Codigo == id
35: select p).First();
36:
37: pessoa.Email = collection["txtEmail"];
38: pessoa.Nome = collection["txtNome"];
39: pessoa.Telefone = collection["txtTelefone"];
40: bd.SaveChanges();
41: }
42: }
43:
44: return RedirectToAction("Index");
45: }
46: catch
47: {
48: return View();
49: }
50: }
Na linha 1, mudei o tipo do parâmetro para Nullable<Int>, isso porque quando eu for criar um novo registro, não vou ter o ID ainda. Na linha 3 eu verifico se o ID está preenchido, se não estiver, considero que é um novo registro e retorna a View com a instância de Pessoa sem as informações preenchidas. Caso tenha valor preenchido, continuo o método como era antes, para ter o comportamento de alteração.
No segundo método, verifico se o ID é um ID novo (valor 0) ou se é uma alteração, e realizo o procedimento adequado, com isso eu utilizo a mesma view tanto para as ações de Criar como Editar, e dessa forma, não replico código de interface (View).
Em alguns casos, em vez de eu criar a lógica na Action dessa forma, eu poderia criar duas Actions com nomes distintos (Create e Edit) e na Create, utilizar o método RedirectToAction, passando como parâmetro o nome do método Edit, são apenas abordagens diferentes, mas que teriam o mesmo resultado. Naturalmente, o método RedirectToAction pode ser utilizados em outros contextos, como eu estou fazendo na linha 44, para redirecionar o navegador para a Action Index, e exibir a listagem atualizada.
Bom, como eu disse o post seria curto, e era isso que tinha para falar.
Clique no link abaixo para baixar o projeto atualizado, inclusive corrigindo um bug do arquivo anterior
.
MvcCrud.zip (641,09 kb)
Até o próximo!
a0480a09-8156-49b2-92d0-f5dadae21956|0|.0