Neste artigo eu vou mostrar como criar uma aplicação ASP .NET Core MVC usando o VS 2017. |
Continuando a oitava parte do artigo vamos usar o Entity Framework Code First Migrations para adicionar um novo campo ao modelo e migrar essa alteração para o banco de dados.
Neste artigo vamos adicionar a lógica de validação ao Model Filme e verificar se as regras são aplicadas sempre que um usuário cria ou edita um filme.
Mantendo as coisas Simples ( DRY-Don´t repeat yourself )
Um dos princípios de design do MVC é conhecido pelo acrônimo DRY ("Do not Repeat Yourself"). A ASP.NET MVC incentiva você a especificar a funcionalidade ou o comportamento apenas uma vez e, em seguida, fazer com que ele seja refletido em toda parte da sua aplicação. Isso reduz a quantidade de código que você precisa para escrever e torna o código menos propenso ao erros, mais fácil de testar e mais fácil de manter.
Nota: O princípio DRY, 'Não se Repita', é um importante princípio que procura reduzir a duplicação de código e os problemas oriundos dessa prática. A definição formal desse princípio diz : "Cada parte do conhecimento deve ter uma representação única, não ambígua e definitiva dentro do sistema."
O suporte de validação fornecido pelo MVC e pelo Entity Framework Core Code First é um bom exemplo do princípio DRY em ação. Você pode declarativamente especificar regras de validação em um lugar (na classe do modelo) e as regras são aplicadas em todos os lugares na aplicação
Adicionando regras de validação ao Model Filme
Para
aplicar as regras no Model Filme vamos usar o recurso DataAnnotations.
A DataAnnotations fornece um conjunto embutido de atributos de validação
que você aplica declarativamente a qualquer classe ou propriedade. Ela também
contém atributos de formatação como DataType que ajudam na formatação e não
fornecem qualquer validação.
Para saber mais sobre esse assunto veja o artigo : C# - Validando dados com Data Annotations - Macoratti
Abra o arquivo Filme.cs da pasta Models e atualize o código da classe usando os atributos de validação StringLength, RegularExpression e Range :
using System;
using System.ComponentModel.DataAnnotations;
namespace MvcFilme.Models
{
public class Filme
{
public int ID { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Titulo { get; set; }
[Display(Name = "Data de Lançamento")]
[DataType(DataType.Date)]
public DateTime Lancamento { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
[Required]
[StringLength(30)]
[Display(Name = "Gênero")]
public string Genero { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Display(Name = "Preço")]
public decimal Preco { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
[StringLength(5)]
[Required]
public string Classificacao { get; set; }
}
}
|
Os atributos de validação especificam o comportamento que você deseja aplicar nas propriedades do modelo ao qual são aplicados.
Os atributos Required e MinimumLength indicam que uma propriedade deve ter um valor; Mas nada impede que um usuário entre com espaço em branco para satisfazer essa validação.
O atributo RegularExpression é usado para limitar quais caracteres podem ser inseridos. No código acima, Genero e Classificacao devem usar apenas letras (espaço em branco, números e caracteres especiais não são permitidos).
O atributo Range restringe um valor dentro de um intervalo especificado.
O atributo StringLength permite definir o comprimento máximo de uma propriedade string e, opcionalmente, seu comprimento mínimo.
Tipos de
valor (como decimal, int, float, DateTime) são inerentemente necessários
e não é necessário o atributo [Required].
Ter regras de validação automaticamente aplicadas pelo ASP.NET ajuda a tornar o
aplicativo mais robusto. Ele também garante que você não se esqueça de validar
algo e, inadvertidamente, deixar dados sujos no banco de dados.
Validação de erros na Interface de Usuário (UI)
Agora vamos executar a aplicação e criar um novo filme informando dados inválidos. Você vai obter o seguinte resultado:
Observe como o formulário automaticamente processou uma mensagem de erro de validação apropriada em cada campo que contém um valor inválido.
Os erros
são aplicados tanto do lado do cliente (usando JavaScript e jQuery) e do
lado do servidor (no caso de um usuário que tem o JavaScript desativado).
Um benefício significativo é que você não precisa alterar uma única linha de
código na classe FilmesController ou na View Create.cshtml para
habilitar essa validação da UI. O controlador e as Views criadas anteriormente
captaram automaticamente as regras de validação que você especificou utilizando
atributos de validação nas propriedades da classe do modelo Filme. Faça o
teste de validação usando o método Action Editar, e a mesma validação será aplicada.
Os dados do formulário não são enviados para o servidor até que não haja erros
de validação do lado do cliente.
Como a validação Funciona ?
Você pode estar perguntando como a validação da View foi gerada sem nenhuma atualização do código do controlador nem nas views Create nem Edit ?
Vamos da um espiada nos dois métodos Create do controlador FilmesController :
// GET: Filmes/Create
public IActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,Titulo,Lancamento,Genero,Preco,Classificacao")] Filme filme)
{
if (ModelState.IsValid)
{
_context.Add(filme);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(filme);
}
|
O
primeiro método Create(HTTP GET) exibe o formulário Create
inicial. A segunda versão de Create ([HttpPost]) processa a postagem (Post)
do formulário e chama o método ModelState.IsValid para verificar se o
filme tem qualquer erro de validação.
Chamar este método avalia quaisquer atributos de validação que foram aplicados
ao objeto. Se o objeto tiver erros de validação, o método Create re-exibe o
formulário. Se não houver erros, o método salva o novo filme no banco de dados.
Em nosso exemplo de filme, o formulário não é enviado ao servidor quando há
erros de validação detectados no lado do cliente; O segundo método Create
nunca é chamado quando há erros de validação do lado do cliente.
Se você desativar o JavaScript em seu navegador, a validação do cliente será
desabilitada e você poderá testar o método HTTP POST Create onde teremos
ModelState.IsValid detectando quaisquer erros de validação.
Você pode definir um ponto de interrupção no método [HttpPost] Create e
verificar que o método nunca é chamado, a validação do lado do cliente não irá
enviar os dados do formulário quando erros de validação são detectados.Tente
desabilitar o JavaScript em seu navegador, e envie o formulário com erros, o
ponto de interrupção será atingido. Assim você ainda tem a validação completa
mesmo sem JavaScript.
Se você abrir o arquivo Create.cshtml verá o código mostrado abaixo que é usado pelo método Create para exibir o formulário inicial e para re-exibir o form quando um error ocorrer:
...
<form asp-action="Create">
<div class="form-horizontal">
<h4>Filme</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Titulo" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Titulo" class="form-control" />
<span asp-validation-for="Titulo" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Classificacao" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Titulo" class="form-control" />
<span asp-validation-for="Classificacao" class="text-danger"></span>
</div>
</div>
...
|
A Tag
Helper input usa os atributos DataAnnotations e produz atributos HTML
necessários para a validação jQuery no lado do cliente. O Validator Tag
Helper exibe erros de validação.
O que é realmente agradável sobre essa abordagem é que nem o controlador nem a
view Create sabem nada sobre as regras de validação reais sendo aplicadas
ou sobre as mensagens de erro específicas exibidas. As regras de validação e as
strings de erro são especificadas somente na classe Filme. Essas mesmas
regras de validação são aplicadas automaticamente à visualização Edit e a
quaisquer outros modelos de visualizações que você possa criar que editam seu
modelo.
Quando você precisa alterar a lógica de validação, pode fazê-lo exatamente em um
lugar, adicionando atributos de validação ao modelo (neste exemplo, a classe
Filme). Você não terá que se preocupar com diferentes partes do aplicativo
que não sejam consistentes com a forma como as regras são aplicadas - toda a
lógica de validação será definida em um lugar e usado em todos os lugares. Isso
mantém o código muito limpo, e o torna fácil de manter e evoluir. E isso
significa que você estará honrando totalmente o princípio DRY.
Usando atributos DataType
Abra o arquivo Filme.cs e examine a classe Filme.
O namespace System.ComponentModel.DataAnnotations fornece atributos de formatação para além do conjunto incorporado de atributos de validação.
Já aplicamos um valor de enumeração DataType para a data de lançamento e para os campos de preço.
O trecho de código a seguir mostra as propriedades DataLancamento e Preco com o atributo DataType apropriado.
public class Filme { public int ID { get; set; } [StringLength(60, MinimumLength = 3)]
[Required]
public string Titulo { get; set; }
[Display(Name = "Data de Lançamento")]
[DataType(DataType.Date)]
public DateTime Lancamento { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
[Required]
[StringLength(30)]
[Display(Name = "Gênero")]
public string Genero { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Display(Name = "Preço")]
public decimal Preco { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
[StringLength(5)]
[Required]
public string Classificacao { get; set; }
}
|
Os
atributos DataType fornecem somente sugestões para o mecanismo de
visualização para formatar os dados e fornecer atributos como <a> para
URLs e <a href="mailto:EmailAddress.com"> para o email.
Você pode usar o atributo RegularExpression para validar o formato dos
dados. O atributo DataType é usado para especificar um tipo de dados que
é mais específico do que o tipo intrínseco do banco de dados, eles não são
atributos de validação. Nesse caso, só queremos manter o controle da
data, e não da hora. A enumeração DataType fornece muitos tipos de dados,
como Date, TIme, PhoneNumber, Currency, EmailAddress
e etc.
O atributo DataType também pode permitir que o aplicativo forneça
automaticamente recursos específicos de tipo. Por exemplo, um link mailto:
pode ser criado para DataType.EmailAddress e um seletor de data pode ser
fornecido para DataType.Date em navegadores que suportam HTML 5. Os
atributos DataType emitem atributos HTML 5-data, que navegadores HTML 5
podem entender. Assim os atributos DataType não fornecem qualquer validação.
O atributo DataType.Date não especifica o formato da data que é exibida.
Por padrão, o campo de dados é exibido de acordo com os formatos padrão com base
no CultureInfo do servidor. Para exibir especificamente o formatao da da
Data usamos o atributo DisplayFormat:
...
[Display(Name = "Data de Lançamento")]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
[DataType(DataType.Date)]
public DateTime Lancamento { get; set; }
...
|
A
configuração ApplyFormatInEditMode especifica que a formatação também
deve ser aplicada quando o valor é exibido em uma caixa de texto para edição.
(Talvez você não queira aplicar isso para alguns campos - por exemplo, para
valores de moeda, você provavelmente não vai querer o símbolo de moeda na caixa
de texto para edição.)
Você pode usar o atributo DisplayFormat por si só, mas geralmente é uma
boa idéia usar o atributo DataType. O atributo DataType transmite a
semântica dos dados em vez de como processá-lo em uma tela e fornece os
seguintes benefícios que você não obtém com DisplayFormat:
- O navegador pode ativar recursos HTML5 (por exemplo, para mostrar um
controle de calendário, o símbolo de moeda apropriado à localidade, links de
e-mail, etc.)
- Por padrão, o navegador renderizará dados usando o formato correto com base em
sua localidade
- O atributo DataType pode habilitar o MVC para escolher o modelo de campo
correto para processar os dados (o DisplayFormat por si mesmo usa o modelo
string).
Nota: A validação jQuery não funciona com o atributo Range e DateTime.
Para concluir podemos simplificar o código combinando os atributos em uma única linha conforme mostrado a seguir:
public class Filme
{
public int ID { get; set; }
[StringLength(60, MinimumLength = 3)]
public string Titulo { get; set; }
[Display(Name = "Data de Lançamento"), DataType(DataType.Date)]
public DateTime Lancamento { get; set; }
[Display(Name = "Gênero"), RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$"), Required, StringLength(30)]
public string Genero { get; set; }
[Display(Name = "Preço"), Range(1, 100), DataType(DataType.Currency)]
public decimal Preco { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$"), StringLength(5)]
public string Classificacao { get; set; }
}
|
Na próxima parte do artigo, analisaremos o aplicativo e faremos algumas melhorias nos métodos Details e Delete gerados automaticamente.
"(Disse Jesus)Eu sou a
porta; se alguém entrar por mim, salvar-se-á, e entrará, e sairá, e achará
pastagens.
O ladrão não vem senão a roubar, a matar, e a destruir; eu vim para que tenham
vida, e a tenham com abundância."
João 10:9,10
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências: