Asp.Net MVC - Enviando dados para o servidor com KnockoutJS e JQuery    

Olá pessoal.

Já faz um tempo que falei de KnockoutJS. Hoje vou falar mais uma vez para tirar uma dúvida recorrente aqui no blog: Como enviar dados do meu modelo KnockoutJS para uma Action do MVC.

Vou fazer um exemplo simples e objetivo. Como o título do post diz, a ideia é mostrar apenas o envio dos dados para o servidor, como obter do servidor não será abordado (quem sabe em outro post).

Vamos explicar como será a aplicação na imagem abaixo:

Imagem 1 – Tela de cadastro.

Imagem 1 – Tela de cadastro.

A tela é divida em três partes:

  1. Na primeira parte é exibido um formulário onde você pode digitar dados de contato e clicar em adicionar
  2. Na segunda parte são exibidos os contatos já adicionados. Você pode clicar no link Remover no final de cada linha para remover o item já adicionado.
  3. Na terceira parte você pode clicar no botão Salvar. Apenas após clicar nesse botão seus dados adicionados a lista serão enviados para o servidor.

A aplicação é bem simples, mas é o suficiente para mostra como enviar dados do JavaScript para o servidor.

Vamos agora ver como a tela foi feita.

   1:  <h3>Cadastro:</h3>
   2:   
   3:  <label for="nome">Nome</label>
   4:  <input id="nome" name="nome" type="text" data-bind="value:Nome" /><br />
   5:  <label for="telefone">Telefone</label>
   6:  <input id="telefone" name="telefone" type="text" data-bind="value:Telefone" /><br />
   7:  <label for="email">E-mail</label>
   8:  <input id="email" type="email" name="email" data-bind="value:Email" /><br />
   9:  <input type="button" data-bind="click:adicionarContato" value="Adicionar >>" />
  10:   
  11:  <table>
  12:      <thead>
  13:          <th>Nome</th>
  14:          <th>Telefone</th>
  15:          <th>E-mail</th>
  16:          <th></th>
  17:      </thead>
  18:      <tbody data-bind="foreach: Contatos">
  19:          <tr>


  21:              <td><input type="text" data-bind="value:Telefone" /></td>
  22:              <td><input type="text" data-bind="value:Email" /></td>
  23:              <td><a href='#' data-bind='click: MeuModelo.removerContato'>Remover</a></td>
  24:          </tr>
  25:      </tbody>
  26:  </table>
  27:  <input type="button" value="Salvar" data-bind="click:salvarContato" />

Esse é todo o HTML utilizado para fazer a tela acima. Da 1 à 9 crio o formulário para adicionar contatos. Da linha 11 à 26 crio a tabela que é exibido os registros adicionados, e por fim na linha 27 adiciono o botão para salvar no servidor.

Repare que em todos os campos estou adicionando o atributo data-bind do KnockoutJS. Para os botões informo que vou utilizar o evento click para invocar o respectivo método do meu modelo (abaixo). Para os campos (input) informo no data-bind que desejo que o atributo value seja preenchido  com o respectivo valor.

Para utilizar o KnockoutJS, posso fazer o download direto no site http://knockoutjs.com ou apenas utilizar o Nuget. No meu caso vou utilizar o Nuget com o comando abaixo no Visual Studio:

PM> Install-Package knockoutjs

Uma vez executado, todos os arquivos necessários para utilizar o Knockout estarão na pasta de Scripts do meu site:

Imagem 2 – Scripts do Site

Imagem 2 – Scripts do Site.

Também vou adicionar a referência para o Jquery e para a biblioteca do KnockoutJS que acabamos de instalar:

<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.2.1.js")"></script>

Agora vamos ao JavaScript necessário para fazer minha aplicação funcionar:

   1:  <script type="text/javascript">
   2:  var MeuModelo = {
   3:      Nome: ko.observable(),
   4:      Telefone: ko.observable(),
   5:      Email: ko.observable(),
   6:      Contatos: ko.observableArray([]),
   7:      adicionarContato: function () {
   8:          this.Contatos.push({ Nome: this.Nome(), Telefone: this.Telefone(), Email: this.Email() })
   9:          this.Nome("");
  10:          this.Telefone("");
  11:          this.Email("");
  12:      }
  13:      , removerContato: function (contato) {
  14:          MeuModelo.Contatos.remove(contato);
  15:      }
  16:      , salvarContato: function () {
  17:          var dados = ko.toJS(MeuModelo.Contatos);
  18:          $.ajax({
  19:              type: "POST",
  20:              contentType: "application/json",
  21:              url: "Home/SalvarContato",
  22:              data: JSON.stringify({ contatos: dados }),
  23:              traditional: true,
  24:              success: MeuModelo.sucesso,
  25:              error: MeuModelo.falha
  26:          });
  27:      }
  28:      ,sucesso: function () { alert("Sucesso");}
  29:      ,falha: function () { alert("Falha"); }
  30:   
  31:      };
  32:   
  33:  ko.applyBindings(MeuModelo);
  34:  </script>

No JavaScript acima estou criando um ViewModel, ou seja, um modelo para gerenciar minha View. Vamos explicar linha por linha:

  • Da linha 3 a 5 estou criando as propriedades observáveis para os três campos do formulário que adiciona os contatos.
  • Na linha 6 estou criando o Array observável que conterá os registros da lista da tela.
  • Entre as linhas 7 e 12 crio o método que será chamado quando for clicado no botão Adicionar. Esse método adiciona os valores atuais das propriedades criadas entre as linhas 3 e 5 ao Array Contatos. Uma vez que o Array muda no JavaScript, a tela atualiza automaticamente. Esse é o KnockoutJS em ação. Para finalizar o método, entre as linhas 9 e 11 eu limpo os campos onde os valores foram digitados.
  • Entre as linhas 13 e 15 eu implemento o método responsável por remover um item do array e atualizar a tela quando clicado no link Remover na lista.
  • Entre as linhas 16 e 29 eu crio o método responsável por enviar os dados ao Servidor. Primeiramente, na linha 17 eu transforme o meu Array observável em um Array puro de JavaScript utilizando o método do KnockoutJS chamado ko.toJS. Em seguida invoco o método ajax do JQuery, invocando o método POST e definido que o conteúdo será do tipo “application/json”. Para enviar os dados ao servidor, eu transformo meus dados em uma string JSON, encapsulando o Array em um campo com o mesmo nome do parâmetro da Action. (Linha 22)
  • Por fim, na linha 33 eu aplico o Binding entre o meu modelo JavaScript e a minha página HTML.

Agora, por último, devemos ver como criar a Action em meu Controller MVC.

É bem simples. Primeiro crio um ViewModel de Contato em meu C#, e em seguida crio uma Action que recebe um um array desse ViewModel:

   1:  namespace Mvc_Knockout.Models
   2:  {
   3:      public class Contato
   4:      {
   5:          public string Nome { get; set; }
   6:          public string Telefone { get; set; }
   7:          public string Email { get; set; }
   8:      }
   9:  }

E a Action:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public JsonResult SalvarContato(Contato[] contatos)
   3:  {
   4:      foreach (var contato in contatos)
   5:      {
   6:          //Lógica para salvar
   7:      }
   8:      return Json(contatos);
   9:  }

Informo que minha Action receberá um Post, e não um simples Get, pois informei na chamada Ajax que enviaria um Post. Uma vez que os dados estiverem no servidor, você pode utilizar a lógica e ferramenta que achar melhor para persistir, como NHibernate ou Entity Framework.

Veja abaixo o print dos meus dados no servidor após clicar no botão Salvar. (Os mesmos dados que estão na tela da imagem da tela (Imagem 1))

 

Imagem 3 – Dados no Servidor.

Imagem 3 – Dados no Servidor.

É isso pessoal. Por hoje era isso.

Até o próximo.

Fonte do Projeto:

Mvc+Knockout.zip (3,01 mb)

18. fevereiro 2013 23:57 by Frederico B. Emídio | Comments (1) | Permalink

Asp.Net MVC – Preenchando campos da View a partir do JavaScript (JQuery, KnockoutJS, etc)    

Olá Pessoal!

Atualmente, todo bom desenvolvedor se preocupa com a experiência do usuário. Não é a toa que bibliotecas JavaScript, como JQuery, tem se popularizado tanto. Nós queremos dar a melhor experiência para o usuário e o único jeito é abusar de JavaScript e Ajax.

Porém, quando começamos a fazer uma interface muito rica, normalmente fazemos todo o controle da View no JavaScript, e acabamos fazendo muitos request para preencher uma única página.

Por exemplo, se eu estiver utilizando KnockoutJS, e minha página for um pouco mais complexa, meu ViewModel começará a ficar extenso. Veja por exemplo esse tutorial do próprio site do KnockoutJS, que apesar de ser simples, já demanda um pouco mais de JavaScript. Num exemplo real, o JavaScript fica imenso.

E como recuperar os dados do servidor e fazer esse Model ser renderizado na página? Muitas vezes fazemos como era possível no WebForms:

  1. Renderizamos a Página
  2. Requisitamos os dados via Ajax
  3. Retornamos os dados.
  4. Preenchemos o ViewModel

O problema é que essa solução, além de fazer dois Request, no mínimo, faz a página “piscar” geralmente, afinal, ela aparece momentaneamente sem os dados, e depois os dados aparecem.

Por exemplo, imagine o simples modelo abaixo:

   1: <script src="../../Scripts/knockout-1.3.0beta.js" type="text/javascript"></script>
   1:  
   2: <div data-bind="with: Autor">
   3:     <p>
   4:         Nome : <span data-bind="text: Nome"></span>
   5:     </p>
   6:     <p>
   7:         E-mail: <span data-bind="text: Email"></span>
   8:     </p>
   9:     <h2>
  10:         Posts</h2>
  11:     <ul data-bind="foreach:Posts">
  12:         <li><span data-bind="text:Titulo"></span>
  13:     </li></ul>
  14: </div>
  15: <script type="text/javascript"> 
  16:  
  17:     var meuModelo = {
  18:         Autor: {
  19:             Nome: "Frederico",
  20:             Email: "teste@teste.com",
  21:             Posts: [
  22:                     { Titulo: "Post 1" },
  23:                     { Titulo: "Post 2" },
  24:                     { Titulo: "Post 3" },
  25:                     { Titulo: "Post 4" }
  26:                 ]
  27:         }
  28:     } 
  29:  
  30:     ko.applyBindings(meuModelo);    
</script>

Caso eu queira receber os dados do servidor, no formato JSON, a primeira idéia que viria na cabeça seria a seguinte:

Criar uma Action que retorna os dados do banco de dados:

   1: public JsonResult ObterDados()
   2: { 
   3:    //Buscando no Banco de dados
   4:    var model = new
   5:    {
   6:        Nome = "Frederico",
   7:        Email = "teste@teste.com",
   8:        Posts = new object[]{
   9:            new {Titulo = "Post 1"},
  10:            new {Titulo = "Post 2"},
  11:            new {Titulo = "Post 3"},
  12:            new {Titulo = "Post 4"}
  13:        }
  14:    }; 
  15:    return Json(model, JsonRequestBehavior.AllowGet);
  16: } 

E na minha View, deveria invocar essa Acion de forma assíncrona:

   1: <script type="text/javascript"> 
   2: //faço outro request
   3: $.getJSON("Home/ObterDados", function (dados) {
   4:     //Preencho meus campos.
   5:     ko.applyBindings({ Autor: dados });
   6: });
   7: </script> 

Bom, na minha opinião, a solução ideal vem a seguir:

Renderizando JSON com ajuda do Json Helper

Apesar dos exemplos estarem com Knockout, utilizar o JSONHelper pode ajudar em qualquer situação, afinal, praticamente todos os plugins JQuery fazem uso de JSON.

A solução é muito simples, você não precisa criar duas Action para renderizar a página (Uma Index que apenas retorna a View, e outra que retorna os dados do Model assincronamente). Na própria Index você retorna os dados, como se fosse preencher os campos normalmente, mas na View renderiza os dados como JSON. Veja:

Na Action padrão eu retorno os dados:

   1: public ActionResult Index()
   2: {
   3:    ViewBag.Message = "Welcome to ASP.NET MVC!"; 
   4:    //Buscando no Banco de dados
   5:    var model = new
   6:    {
   7:        Nome = "Frederico",
   8:        Email = "teste@teste.com",
   9:        Posts = new object[]{
  10:            new {Titulo = "Post 1"},
  11:            new {Titulo = "Post 2"},
  12:            new {Titulo = "Post 3"},
  13:            new {Titulo = "Post 4"}
  14:        }
  15:    }; 
  16:    return View(model);
  17: } 

E na View utilizo o helper @Json:

   1: <script type="text/javascript">
   2: var meuModelo = {
   3:     //Faço o retorno da Action ser transformado em JSON
   4:     Autor: @Html.Raw(@Json.Encode(Model))
   5:     //Aqui poderia ter meus outros métodos e propriedades do ViewModel
   6: }
   7: //Preencho meus campos.
   8: ko.applyBindings(meuModelo);
   9: </script> 
 

E o resultado é o mesmo, porém, com apenas um Request, e com o código ligeiramente mais limpo:

image

Veja como o HTML é gerado, o JSON está renderizado como o esperado:

image

Apesar de não ter utilizado nenhum controle Input (textbox), a solução funciona da mesma forma com esses controles.

Bom pessoal, por hoje era isso. Espero que possa te ajudar.

Abraços!

9. setembro 2011 12:00 by Frederico B. Emídio | Comments (0) | Permalink

Como utilizar validação com Asp.Net MVC    

Olá pessoal!

Hoje vou falar de uma tarefa importante no desenvolvimento de sites: Validação.

Na construção de site nós nunca podemos confiar nas informações que o usuário informa, devemos saber que qualquer pessoa pode errar uma digitação ou esquecer de digitar uma informação qualquer, e por isso é importante saber utilizar Validação nos formulários que criamos.

No Asp.Net MVC existem várias formas de realizar validações, mas hoje vou falar de apenas três:

  • Adicionando informações à propriedade ModelState
  • Utilizando DataAnnotations
  • Utilizando DataAnnotations com JQuery

O processo de validação no Asp.Net MVC ficou muito fácil, eu diria que ficou muito mais fácil que no Asp.Net WebForm, vamos então começar pelo básico:

Validando suas Views com ModelState

A validação no Asp.Net MVC sempre é feita através do estado do modelo (ModelState) recebido na Action de um Controller, o que muda é como esse estado é alterado, pois pode feito manualmente, como faremos agora, ou automaticamente, através de ActionFilter customizado ou automático.

A forma básica é você adicionar manualmente informações de erro no modelo ao ModelState, invocando o método AddModelError(chave,mensagemDeErro).

Vamos aos exemplos! Para começar vou criar meu modelo, bem simples, como em todos os meus outros exemplos: Pessoa

   1:  public class Pessoa
   2:  {
   3:      public string Nome { get; set; }
   4:      public string Email { get; set; }
   5:      public string Telefone { get; set; }
   6:      public int Idade { get; set; }
   7:  }

Naturalmente, para criar uma pessoa no banco de dados, algumas informações devem ser obrigatórias e outras devem seguir algum formato específico, para todos os nossos exemplos usaremos as mesmas validações:

  • O nome é obrigatório.
  • O e-mail é obrigatório.
  • O telefone é obrigatório.
  • O e-mail deve seguir o formatado texto@texto.texto
  • A idade é deve ser maior que 18.
  • O telefone deve seguir o formato ####-####

Vou criar duas Actions de nome Edicao, uma para renderizar a View inicial e outra para persistir os dados, essa segunda terá a responsabilidade de fazer a validação do Modelo, e adicionar os erros ao ModelState. Caso não tenha erro, apenas redirecionará o usuário para a página inicial (persistir em uma base de dados não vem ao caso).

Abaixo segue o código das Actions:

   1:  public ActionResult Edicao()
   2:  {
   3:      return View();
   4:  }
   5:   
   6:  [AcceptVerbs(HttpVerbs.Post)]
   7:  public ActionResult Edicao(Pessoa pessoa)
   8:  {
   9:      //Valida os dados no lado do servidor.
  10:      if(string.IsNullOrEmpty(pessoa.Nome))
  11:      ModelState.AddModelError("Nome","Nome é obrigatório");
  12:      
  13:      if (string.IsNullOrEmpty(pessoa.Email))
  14:      ModelState.AddModelError("Email", "Email é obrigatório");
  15:      else{
  16:      if (!Regex.Match(pessoa.Email,@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$").Success)
  17:      ModelState.AddModelError("Email", "E-mail inválido.");
  18:      }
  19:   
  20:      if (pessoa.Idade <= 18)
  21:      ModelState.AddModelError("Idade", "Idade deve ser maior que 18.");
  22:   
  23:      if (string.IsNullOrEmpty(pessoa.Telefone))
  24:      ModelState.AddModelError("Telefone", "Telefone é obrigatório.");
  25:      else
  26:      {
  27:      if (!Regex.Match(pessoa.Telefone, @"^\d{4}[-]{1}\d{4}$").Success)
  28:          ModelState.AddModelError("Telefone", "Preencha um telefone no formato ####-####");
  29:   
  30:      }
  31:      //Verifica se algum erro acima falhou.
  32:      if (!ModelState.IsValid)
  33:      {
  34:      return View();
  35:      }
  36:      else
  37:      {
  38:      //Se estive certo só redireciono para a página inicial.
  39:      return Redirect("/");
  40:      }   
  41:  }

O código é bem intuitivo, caso tenha adicionado alguma mensagem de erro, a propriedade IsValid do ModelState retornará false, e o modelo estará inválido, assim eu retorno minha mesma View, que exibirá as mensagens de erros. Minha View fica da seguinte forma:

   1:  <%using(Html.BeginForm()){ %>
   2:  <p>
   3:  <%=Html.LabelFor(Model=>Model.Nome)%>
   4:  <%=Html.TextBoxFor(Model=>Model.Nome)%>
   5:  <%=Html.ValidationMessage("Nome")%>
   6:  </p>
   7:  <p>
   8:  <%=Html.LabelFor(Model=>Model.Email)%>
   9:  <%=Html.TextBoxFor(Model=>Model.Email)%>
  10:  <%=Html.ValidationMessage("Email")%>
  11:  </p>
  12:  <p>
  13:  <%=Html.LabelFor(Model=>Model.Telefone)%>
  14:  <%=Html.TextBoxFor(Model=>Model.Telefone)%>
  15:  <%=Html.ValidationMessage("Telefone")%>
  16:  </p>
  17:  <p>
  18:  <%=Html.LabelFor(Model=>Model.Idade)%>
  19:  <%=Html.TextBoxFor(Model=>Model.Idade)%>
  20:  <%=Html.ValidationMessage("Idade")%>
  21:  </p>
  22:  <p>
  23:  <input type="submit" value="Salvar"/>
  24:  </p>
  25:  <%} %>

Veja que a única novidade da minha View a utilização do HTMLHelper ValidationMessage, passando o nome da chave que eu valido no servidor. Ao executar minha tela, caso passe informações inválidas, terei o seguinte resultado:

image

Ou assim:

image

E a sua validação está pronta para ser usada! Eu poderia utilizar um ValidationSummary, apenas utilizando o helper para isso, da seguinte forma: <%=Html.ValidationSummary()%>.

Vamos à nossa segunda forma de validar nosso modelo.

Validando suas Views com DataAnnotarions

DataAnnotations é uma forma de você adicionar validações ao seu modelo através de atributos, incorporada ao .Net 4. O interessante dessa estratégia é que não está ligada ao Asp.Net MVC, portanto, você pode utilizá-la tanto em Asp.Net, como em qualquer outra tecnologia .Net, como WCF. Isso é muito importante, pois você não precisa repetir validação em diversas partes do código, técnica conhecida como DRY (Don’t Repeat Yourself).

Como a validação é centralizada no modelo, nosso modelo sofrerá uma pequena alteração, assim como nossa Action, pois tiraremos a validação da Action e passaremos para o modelo. Nosso modelo ficará assim:

   1:  public class Pessoa
   2:  {
   3:      [Required(ErrorMessage = "O Nome é obrigatório.")]
   4:      public string Nome { get; set; }
   5:   
   6:      [Required(ErrorMessage = "O E-mail é obrigatório.")]
   7:      [RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "E-mail inválido.")]
   8:      public string Email { get; set; }
   9:   
  10:      [Required(ErrorMessage = "O Telefone é obrigatório.")]
  11:      [RegularExpression(@"^\d{4}[-]{1}\d{4}$", ErrorMessage = "Telefone inválido. Informe ####-####.")]
  12:      public string Telefone { get; set; }
  13:   
  14:      [Range(18, Int16.MaxValue, ErrorMessage = "A idade deve ser maior que 18 anos.")]
  15:      public int Idade { get; set; }
  16:  }

Veja que existem vários tipos de atributos de Validação, e para todos eu posso informar uma mensagem de erro personalizada, através da propriedade ErrorMessage, além de cada um ter propriedades específicas de acordo com o tipo.

Como toda a lógica de validação passou para o modelo, nossa Action ficará bem mais simples:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Edicao(Pessoa pessoa)
   3:  {
   4:      //O modelo já chega validado
   5:      if (!ModelState.IsValid)
   6:      {
   7:      return View();
   8:      }
   9:      else
  10:      {
  11:      //Se estive certo só redireciono para a página inicial.
  12:      return Redirect("/");
  13:      }
  14:  }

Veja como ficou simples a Action agora, e o resultado nas Views é o mesmo, não mudei nada no meu HTML, apenas adicionei um Summary, para ver que o resultado é o mesmo:

image

E mais uma forma de validação já está funcionando e pronta para publicar!

Mas espera aí! Existe um problema nessas duas formas de validação: Ela são realizadas no servidor. Ou seja, o usuário precisa ser submetido ao servidor para realizar a validação, o que pode prejudicar muito a experiência do usuário, e para isso termos a terceira forma de validação de hoje:

Utilizando DataAnnotations com JQuery para validação no Cliente

O mais interessante da utilização do JQuery com DataAnnotation é o impacto no código do servidor: Nada! Isso mesmo, não tem impacto nenhum no servidor para você adicionar validação no Asp.Net MVC no cliente. Vou fazer a seguinte alteração no HTML:

 

   1:  <% Html.EnableClientValidation();%>
   2:  <%using (Html.BeginForm())
   3:  { %>
   4:  <p>
   5:  <%=Html.LabelFor(Model=>Model.Nome)%>
   6:  <%=Html.TextBoxFor(Model=>Model.Nome)%>
   7:  <%=Html.ValidationMessageFor(Model => Model.Nome)%>
   8:  </p>
   9:  <p>
  10:  <%=Html.LabelFor(Model=>Model.Email)%>
  11:  <%=Html.TextBoxFor(Model=>Model.Email)%>
  12:  <%=Html.ValidationMessageFor(Model => Model.Email)%>
  13:  </p>
  14:  <p>
  15:  <%=Html.LabelFor(Model=>Model.Telefone)%>
  16:  <%=Html.TextBoxFor(Model=>Model.Telefone)%>
  17:  <%=Html.ValidationMessageFor(Model => Model.Telefone)%>
  18:  </p>
  19:  <p>
  20:  <%=Html.LabelFor(Model=>Model.Idade)%>
  21:  <%=Html.TextBoxFor(Model=>Model.Idade)%>
  22:  <%=Html.ValidationMessageFor(Model => Model.Idade)%>
  23:  </p>
  24:  <p>
  25:  <input type="submit" value="Salvar" />
  26:  </p>
  27:  <%} %>

As alterações na view foram pequenas, adicionei o Helper EnableClientValidation e mudei ValidationMessage por ValidationMessageFor, fora isso, foi necessário adicionar referência a alguns arquivos JS (JavaScript), você pode adicionar tanto no seu arquivo de Layout  (Master) ou na própria View. Os arquivos são os seguintes:

 

   1:  <script src="<%=Url.Content("~/Scripts/jquery-1.4.1.min.js")%>" type="text/javascript"></script>
   2:  <script src="<%=Url.Content("~/Scripts/jquery.validate.js")%>" type="text/javascript"></script>
   3:  <script src="<%=Url.Content("~/Scripts/MicrosoftMvcJQueryValidation.js")%>" type="text/javascript"></script>
 

Os arquivos que adicionei são os arquivo do próprio JQuery (a versão desatualizada que vem com o Visual Studio 2010, que você pode mudar para a atual), o plug-in Validate do Jquery e um arquivo fornecido pelo time do Asp.Net para fazer o meio campo entre a validação do Asp.Net com o JQuery de forma totalmente transparente. Esse arquivo pode ser baixado com o Asp.Net MVC Futures, clicando aqui.

O Resultado é o mesmo:

image

E assim sua validação já estará funcionando no cliente. O mais legal dessa abordagem é que você realizará a validação tanto no Cliente como no Servidor, sem repetir uma linha de código (DRY).

No servidor que eu digo não é como no WebForm, onde a validação de um Validator Control também funciona tanto no servidor como no cliente, porque naquele caso, é apenas no servidor Asp.Net, visto que a validação está na página. Nesse caso, a validação está no Modelo, logo, o mesmo código pode ser utilizado em uma classe de negócio, WCF, WWF, etc; sem replicação de código.

Existe uma validação nativa no lado do Cliente no MVC, mas preferi mostrar com o Jquery, porque é possível integrar outros plug-ins com a validação, que podem gerar efeitos bem interessantes à sua página.

Bom, acredito que seja o suficiente para você adicionar validação ao sua página, de forma bem clara sem ter que se esforçar muito.

Abaixo você pode baixar uma solução contendo três projetos, um com cada tipo de validação, para você ver que não existe grandes diferenças entra elas.

Abraços e até o próximo pessoal.

ValidatorsMVC.zip (1,00 mb)

27. fevereiro 2011 06:06 by Frederico B. Emídio | Comments (0) | Permalink

Reaproveitando View em Asp.Net MVC    

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 Smiley de boca aberta.

MvcCrud.zip (641,09 kb)

Até o próximo!



  
     
  
25. janeiro 2011 11:23 by Frederico B. Emídio | Comments (0) | Permalink

Utilizando Ajax com Asp.Net MVC    

Olá pessoal, hoje vou falar de um assunto que é de extrema importância para desenvolvimento Web atualmente: Ajax.

Para quem não sabe, Ajax é o acrônimo de Asynchronous Javascript And XML, e que na  prática nada mais é que a capacidade de postar informações ao servidor, sem a necessidade de enviar a página inteira, e receber apenas uma pequena informação, sem a necessidade de atualizar a página toda. Para saber mais, clique no link do nome.

Hoje em dia, Ajax virou praticamente um conceito de atualização parcial de páginas Web, digo isso, porque Ajax em si não é mais utilizado na grande maioria das vezes! É isso mesmo, se reparar no nome completo, o X do Ajax é XML, e normalmente não utilizamos XML para a comunicação, mas sim JSON, ou seja, o que utilizamos de fato é chamado muitas vezes em blog e artigos pela Web de AJAJ (Asynchronous Javascript And JSON).

A responsabilidade de fazer a comunicação de forma assíncrona é do navegador, através do objeto XMLHttpRequest (IE 7+, e demais browsers) ou do Microsoft.XMLHTTP (IE 5 e 6). No nosso caso, não precisamos saber disso, porque utilizaremos JQuery para encapsular toda a lógica de criação da comunicação.

Apesar de usarmos JQuery, nós poderiamos utilizar outros frameworks JavaScript para encapsular a lógica de comunicação. A própria Microsoft disponibilizar nos projetos Web o framework MicrosoftAjax.js, que é extremamente bom. Com esse framework, inclusive, você pode acessar funcionalidades do Asp.Net, como a parte de Authentication.

Bom, mas vamos ao que interessa.

Utilizando JQuery para fazer chamadas assíncronas em Asp.MVC

No Jquery existe uma forma básica de se comunicar assincronamente com o servidor, que é o método $.ajax. Este método contém todas as informações necessárias para uma comunicação, nele você pode definir a url, o método de retorno em caso de sucesso e em caso de falha, tipo do dado passado (onde você pode passar uma sério de Content-Type, como json, xml, text, etc), verbo HTTP (get, post, etc), e mais uma série de opções. Como não utilizaremos esse método, você pode clicar aqui para ver uma lista detalhada de opções.

Não utilizaremos esse método, porque existem dois métodos que abstraem bastante a utilização dele, e que são suficientes para a maioria das situações, são os métodos $.post e $.get.

Estes métodos basicamente invocam o método $.ajax, passando no parâmetro type o tipo post ou get. O único problema é que ele não retorna erro, ou seja, se tiver algum problema no seu código que faça ter algum erro, você vai ficar sem saber até quebrar um pouco a cabeça, o ideal é: Quando tiver algum comportamento estranho, mude o método para $.ajax, e defina o parâmetro error, assim poderá ver qual a mensagem de erro está sendo retornada do servidor.

Nosso site fará quatro testes:

  • Obter informação do servidor via Get
  • Enviar informação para o servidor via Get
  • Enviar informação para o servidor via Post através de parâmetros
  • Enviar informação para o servidor via Post através de um objeto.

Abaixo segue o código do Controller com suas Action:

   1:  public JsonResult ObterGet()
   2:  {
   3:      var json = new { Nome = "Nome do Servidor", Idade = 20 };
   4:      return Json(json, JsonRequestBehavior.AllowGet);
   5:  }
   6:   
   7:  public JsonResult EnviarGet(string nome, int idade)
   8:  {
   9:      var json = new { Nome = nome + " Servidor", Idade = idade + 1 };
  10:      return Json(json, JsonRequestBehavior.AllowGet);
  11:  }
  12:   
  13:  public JsonResult EnviarPost(string nome, int idade)
  14:  {
  15:      var json = new { Nome = nome + " Servidor", Idade = idade + 1 };
  16:      return Json(json);
  17:  }
  18:   
  19:  public JsonResult EnviarObjeto(Pessoa p)
  20:  {
  21:   
  22:      p.Nome += " Servidor";
  23:      p.Idade += 1;
  24:      return Json(p);
  25:  }

Os códigos são bem simples: Os métodos de GET (ObterGet e EnviarGet) precisam passar uma informação a mais no método Json pois o MVC força você a dizer que quer retornar uma chamada get, mesmo sabendo do risco que isso pode ser. É um risco porque um site de outro domínio pode invocar esse método utilizando GET, e se você não informar que isso aconteça, o ASP.NET vai barrar a chamada, retornado  a mensagem:

This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.

Como queremos testar o Get, então permitimos essa comunicação, adicionando o parâmetro JsonRequestBehavior.AllowGet. Para os métodos utilizados através de POST (EnviarPost e EnviarObjeto) não precisamos utilizar esse parâmetro.

Para o método EnviarObjeto funcionar, criei uma classe simples, que segue abaixo:

   1:  public class Pessoa
   2:  {
   3:      public string Nome { get; set; }
   4:      public int Idade { get; set; }
   5:  }

Para consumir esses métodos, criei o HTML abaixo:

<p>Nome:<input type="text" id="txtNome" /></p>
<p>Idade:<input type="text" id="txtIdade" /></p>
<input type="button" value="Enviar Get" onclick="enviarGet();"/>
<input type="button" value="Enviar Post" onclick="enviarPost();"/>
<input type="button" value="Enviar Objeto" onclick="enviarObjeto();"/>
<input type="button" value="Obter" onclick="javascript:obter();"/>

Sua visualização será essa:

image

E o Javascript da página será:

   1:  function obterCallback(retorno,status) {
   2:      $("#txtNome").val(retorno.Nome);
   3:      $("#txtIdade").val(retorno.Idade);
   4:  }
   5:  function obter() {
   6:      $.get("Ajax/ObterGet", obterCallback);
   7:  }
   8:   
   9:  function enviarGet() {
  10:      if ($("#txtNome").val() == "" || $("#txtIdade").val() == "") {
  11:          alert("Preencha todas os campos!");
  12:          return;
  13:      }
  14:      $.get("Ajax/EnviarGet",
  15:      { nome: $("#txtNome").val(), idade: $("#txtIdade").val() },
  16:         obterCallback
  17:      );
  18:  }
  19:   
  20:  function enviarPost() {
  21:      if ($("#txtNome").val() == "" || $("#txtIdade").val() == "") {
  22:          alert("Preencha todas os campos!");
  23:          return;
  24:      }
  25:      $.post("Ajax/EnviarJson",
  26:      { nome: $("#txtNome").val(), idade: $("#txtIdade").val() },
  27:         obterCallback
  28:      );
  29:  }
  30:   
  31:  function enviarObjeto() {
  32:      if ($("#txtNome").val() == "" || $("#txtIdade").val() == "") {
  33:          alert("Preencha todas os campos!");
  34:          return;
  35:      }
  36:      $.post("Ajax/EnviarObjeto",
  37:      { nome: $("#txtNome").val(), idade: $("#txtIdade").val() },
  38:         obterCallback
  39:      );
  40:  }

O JavaScript, utilizando o Jquery, é tão simples que nem precisaria de explicação, mas vamos lá: O primeiro parâmetro é o endereço da Action (Controller/Action), o segundo pode ser o método de retorno (Callback) ou os parâmetros que serão passados, caso seja definido parâmetro, o terceiro método é o método de retorno. Existe um quarto parâmetro que não estou utilizando, que seria para informar o tipo do retorno (json, xml, etc). No meu caso não preciso utilizá-lo.

Os parâmetros estou passando através de um objeto JSON, que o Jquery converte em querystring, caso seja GET ou coloca os parâmetros no corpo da mensagem HTTP, caso seja POST. Relembre essas regras aqui.

Para conseguir testar, basicamente eu altero o valor enviado para o servidor e retorno, preenchendo os campos com o novo valor, dessa forma posso ver que as informações estão realmente chegando no servidor e voltando.

Obervação: A Action que recebe as chamadas Assíncronas não precisa estar no mesmo Controller que retornou a View do formulário.

Conclusão

Quis mostrar nesse post como é simples utilizar Ajax juntando MVC e JQuery, tão simples quanto utilizar PageMethods no WebForms, porém, sendo mais rápido para primeira renderização (porque não precisa de ScriptManager para gerar um Proxy).

Obervação 2: No WebForms é possivel utilizar esses métodos do Jquery com os métodos estáticos da página marcados com o atributo WebMethod, dessa forma você não precisaria utilizar o ScriptManager para gerar o próximo PageMethods.

Acho importante esse tipo de conhecimento, pois hoje em dia não existe site ou sistema sem alguma funcionalidade Assícrona, e isso pode ser incluído nos conhecimentos básicos de Asp.Net MVC.

O Link para o exemplo está abaixo.

MvcAjax.zip (292,92 kb)

Bom, por hoje é isso. Até o próximo.


  
     
  
24. janeiro 2011 23:31 by Frederico | Comments (3) | Permalink

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

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

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET