ASP .NET MVC 4 - Criando um Formulário com validação usando o template Basic


Como criar rapidamente um web site simples com um formulário com validação ?

Para criar um web site com um formulário com validação vamos precisar de uma infraestrutura para a validação e para isso podemos criar um projeto ASP .NET MVC 4 usando o template Basic.

Depois de criar o projeto vamos criar um controlador Home com algumas Actions:

Além disso vamos precisar criar views para cada Action e definir um Model para os usuários.

Abra o Visual Studio 2012 Express for web e clique em New Project;

A seguir selecione o template Visual C# ou Visual Basic -> Web e ASP .NET MVC 4 Web Application informando um nome (WebSite_FormValidacao) e clique no botão OK;

A seguir selecione o template Basic e o engine Razor e clique em OK;

Com o projeto criado vamos criar um controlador chamado HomeController que irá conter as Actions para as páginas e o formulário Questionario.

Clique com o botão direito do mouse sobre e selecione Add -> Controller;

Informe o nome HomeController e clique no botão Add;

Obs: Você pode criar um controlador usando o template Empty MVC Controller.

Limpe o código gerado e vamos definir as seguintes Actions:

  1. Index
  2. Questionario
  3. Questionario (usando o atributo [HttPost]) - esta Action irá redirecionar para a Action Obrigado;
  4. Obrigado

O código pode ser visto abaixo:

No método Questionario com HttPost passamos um FormCollection como parâmetro. (Você pode alterar isso usndo um classe customizada). Isto é necessário pois na classe Controller não podemos ter métodos com a mesma assinatura.

Criando o Model

Vamos agora definir o nosso Modelo e como os dados que iremos usar não serão salvos em um banco de dados mas apenas enviados via email, vamos criar uma classe POCO para isso.

Para descrever os nomes exibidos e os requisitos de validação vamos usar o recurso Data Annotations.

Clique com o botão direito sobre a pasta Models e a seguir em Add-> New Item;

Selecione o template Class e informe o nome QuestionarioModel e clique no botão Add;

Inclua o código abaixo na classe QuestionarioModel:

namespace WebSite_FormValidacao.Models
{
    public class QuestionarioModel
    {
        public string TipoProjeto { get; set; }
        public string Cep { get; set; }
        public string Contato { get; set; }
        public string Email { get; set; }
        public string Telefone { get; set; }
        public string Descricao { get; set; }
    }
}

A seguir vamos alterar a Action Questionario em HomeController de forma que ela receba o nosso model QuestionarioModel conforme abaixo:

        using WebSite_FormValidacao.Models;

        [HttpPost]
        public ActionResult Questionario(QuestionarioModel resposta)
        {
            try
            {
                return RedirectToAction("Obrigado");
            }
            catch
            {
                return View();
            }
        }

Criando as Views

Precisamos criar 3 views :

  1. Index - que irá ser a home page do site
  2. Questionario - que os usuários irão acessar para responder ao questionário
  3. Obrigado - a view que irá exibir uma mensagem após o usuário preencher e submeter o formulário

Abra a pasta Controllers e a seguir o arquivo HomeController.

Clique com o botão direito sobre a view Index e selecione Add View;

Informe o nome Index e clique no botão Add;

A seguir defina o código desta view conforme abaixo:

@{
ViewBag.Title = "Macoratti .net - JcmSoft";
}

<h2>Macoratti .net - JcmSoft - Orçamento de Projeto</h2>

Precisando de um projeto de softeware. Temos a solução por um preço justo.<br />

@Html.ActionLink("Solicite um orçamento grátis.","Questionario");

Ainda na Action HomeController e clique com o botão direito sobre a Action Obrigado e selecione Add View;

Informe o nome Questinario e clique no botão Add;

A seguir digite o código abaixo para esta view:

@{
    ViewBag.Title = "Obrigado";
}

<h2>Obrigado</h2>

<h3>Agradecemos a sua solicitação de orçamento.</h3>
<br />
<h3>Entraremos em contato o mais breve possível.</h3>

Retorne a Action HomeController e clique com o botão direito sobre a Action Questionario e selecione Add View;

Informe o nome Questinario e clique no botão Add;

Digite o código para esta view conforme abaixo:

@model WebSite_FormValidacao.Models.QuestionarioModel

@{
   ViewBag.Title = "Solicitação de Orçamento";
  
   List<string> TiposProjetos = new List<string>();
   TiposProjetos.Add("Desktop VB .NET");
   TiposProjetos.Add("Desktop C#");
   TiposProjetos.Add("Web - ASP .NET");
   TiposProjetos.Add("Web - ASP .NET MVC");
   TiposProjetos.Add("Outros");

    <h2>Orçamento</h2>

   @using (Html.BeginForm())
   {
        @Html.ValidationSummary()
        <fieldset>
        <legend>Formulário de Solicitação de  Orçamento</legend>
        <ol>
        <li>
        @Html.LabelFor(m=>m.TipoProjeto)
        @Html.DropDownListFor(m=>m.TipoProjeto, new MultiSelectList(TiposProjetos))
        </li>
        <li>
        @Html.LabelFor(m=>m.Contato)
        @Html.TextBoxFor(m=>m.Contato)
        </li>
        <li>
        @Html.LabelFor(m=>m.Telefone)
        @Html.TextBoxFor(m=>m.Telefone)
        </li>
        <li>
        @Html.LabelFor(m=>m.Email)
        @Html.TextBoxFor(m=>m.Email)
        </li>
        <li>
        @Html.LabelFor(m=>m.Descricao)
        @Html.TextBoxFor(m=>m.Descricao)
        </li>
        </ol>
        <input type="submit" value="Solicitação de Orçamento" />
        </fieldset>
  }

Repita o procedimento e crie a view Obrigado com o seguinte código:

Acima vemos o código do formulário onde na primeira linha temos uma referência ao nosso Model. A vinculação com o Model permite usar o recurso Intellisense para o model facilitando a digitação. A seguir o bloco de código define o título da página e cria uma lista que irá tratar as opções para o dropdownlist.

Exitem diversas formas de criar esta lista quer como parte do model quer dentro do controlador. Desde que a lista é estática e temos apenas uma view colocamos o código na view. Se a mesma lista fosse usada em outras views ou se precisemos obter seus itens de um banco de dados seria melhor colocar o código no model.

Em seguida temos o código Razor envolvendo uma chamada a Html.BeginForm() dentro de um bloco @using(){}, com isso forçamos a chamada do método Html.EndForm().

A seguir temos uma série de instruções @Html.LabelFor e @HtmlTextBoxFor que são usados para criar o formulário. Utilizar os HTML helpers nos permite usar o recurso data annotations no modelo para fornecer detalhes de como os campos serão renderizados. Esses HTML helpers seguem um padrão similar.

Estamos usando LINQ e expressões lambdas onde do lado esquerdo do operador lambda ("=>") esta a lista de parâmetros e no lado direito esta o corpo da função. Na expressão @Html.TextBoxFor(m=>m.Telefone) a chamada é feita para o HTML helper TextBoxFor que passa a expressão lambda m=>m.Telefone. A letra m representa o model passado para view que é do tipo especificado na diretiva @model. O tipo model é automaticamente inferido pelo compilador e não precisa ser explicitado. O engine Intellisense do Visual Studio também infere o tipo e fornece o recurso autocompletar para as propriedades da variável m. Usamos a letra m apenas por convenção.

No lado direito da expressão lambda, o método TextBoxFor espera uma propriedade do model. Em tempo de execução este método irá usar o recurso reflection para obter a informação sober o model e a propriedade passada como parâmetro. Ele então usa a informação para criar os elementos HTML input bem como diversos atributos de dados.

A instrução @Html.DropDownList é um exemplo de HTML Helper mais sofisticado pois neste caso não estamos passando somente a propriedade mas também um MultiSelectList que contém os valores da lista drop-down. No exemplo estamos passando uma string que é usada tanto para exibir o nome como o valor.

Incluindo Data Attributes ao Model

Se executarmos o nosso projeto iremos notar que não existe validação no formulário e que a caixa de texto da descrição do projeto é renderizada como um elemento input e não um text area. Vamos então usar os Data Attributes para resolver esses problemas.

Abra o arquivo QuestionarioModel e altere o seu código conforme abaixo. (As alterações estão destacadas em azul)

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace WebSite_FormValidacao.Models
{
    public class QuestionarioModel
    {
        [Required]
        [DisplayName("Tipo de Projeto")]
        public string TipoProjeto { get; set; }

        [Required(ErrorMessage="O CEP deve ser informado.!")]
        [RegularExpression(@"^\d{8}$|^\d{5}-\d{3}$", ErrorMessage="O código postal deverá estar no formato 00000000 ou 00000-000")]
        [DisplayName("CEP")]
        public string Cep { get; set; }

        [Required(ErrorMessage = "O nome do contato deve ser informado.!")]
        [StringLength(50, MinimumLength = 5)]
        public string Contato { get; set; }

        [Required(ErrorMessage = "O email é obrigatório!")]
        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }

        [Required(ErrorMessage = "O telefone deve ser informado.!")]
        [DataType(DataType.PhoneNumber,ErrorMessage="Forneça o número do telefone no formato (000) 000-0000")]
        [DisplayName("Número do Telefone")]
        public string Telefone { get; set; }

        [Required(ErrorMessage = "Ínforme a descrição do projeto.")]
        [DisplayName("Descrição do Projeto")]
        [StringLength(5000, MinimumLength = 20)]
        [DataType(DataType.MultilineText)]
        public string Descricao { get; set; }
    }
}

Os atributos incluídos descrevem a exibição de nomes, o comprimento máximo e mínimo de cada propriedade, o tipo de dados, e até expressões regulares que descrevem o formato esperado.

Se executarmos o projeto novamente iremos ver que as coisas mudaram mas precisamos ajustar a view para que a descrição do projeto seja renderizada corretamente. Abra o arquivo Questionario.cshtml e altere o HTML Helper TextBoxFor dos campos Contato,Telefone,Email e Descricao para EditorFor conforme abaixo:

 @model WebSite_FormValidacao.Models.QuestionarioModel

@{
    ViewBag.Title = "Questionario";
   
 
  List<string> TiposProjetos = new List<string>();
    TiposProjetos.Add("Desktop VB .NET");
    TiposProjetos.Add("Desktop C#");
    TiposProjetos.Add("Web - ASP .NET");
    TiposProjetos.Add("Web - ASP .NET MVC");
    TiposProjetos.Add("Outros");

}

<h2>Orçamento de Projeto de Software</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary()

    <fieldset class="">
        <legend>Solicitação de Orçamento</legend>

        <div class="editor-label">
            @Html.LabelFor(m => m.TipoProjeto)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(m=>m.TipoProjeto, new MultiSelectList(TiposProjetos))
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Cep)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.Cep)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Contato)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.Contato)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Email)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.Email)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Telefone)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.Telefone)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Descricao)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.Descricao)
        </div>

        <p>
             <input type="submit" value="Solicitação de Orçamento" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

O código alterado foi modificado para permitir a validação e no final do arquivo temos a inclusão do script bundle definido para a validação jQuery e para as bibliotecas de validação discreta (unobtrusive) da Microsoft.

Alteramos também todos os helpers TextBoxFor para EditorFor que é um helper que usa o atributo tipo de dados definido no model para determinar como renderizar o campo, o que fará com que a descrição do projeto seja agora renderizada corretamente.

Abaixo vemos um fragmento do HTML renderizado pela ASP .NET para a view Questionario.cshtml :

Observe os data attributes adicionados ao elementos input do formulário.

Antes de executar o projeto vamos alterar as definições para fieldset e legend e label no arquivo Site.css na pasta Content conforme abaixo:

...
fieldset {
  padding: 1em;
  font:80%/1 sans-serif;
  }
label {
  float:left;
  width:25%;
  margin-right:0.5em;
  padding-top:0.2em;
  text-align:right;
  font-weight:bold;
  }

legend {
   width: 450px;
background: #648E35;
color: #FFFFFF;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 13px;
font-weight: bold;
border: 1px solid #cccccc;
border-bottom-color: #999999;
border-right-color: #999999;
padding: 4px 8px;
}
...

Executando o projeto teremos:

1- A view inicial Index.cshtml

2- A view Questionario.cshtml exibindo o formulário para orçamento e as mensagens de erro de validação para cada campo:

3 - A view Questionario.cshtml corretamente preenchida

4- A view Obrigado.cshtml

Pegue o projeto completo aqui:   WebSite_FormValidacao.zip

1Ts 5:9 porque Deus não nos destinou para a ira, mas para alcançarmos a salvação por nosso Senhor Jesus Cristo,

1Ts 5:10 que morreu por nós, para que, quer vigiemos, quer durmamos, vivamos juntamente com ele.

1Ts 5:11 Pelo que exortai-vos uns aos outros e edificai-vos uns aos outros, como na verdade o estais fazendo.

Referências:


José Carlos Macoratti