RSS feed
Validação do Modelo no Nível das Classes com a EF Code First e ASP.NET MVC 3 - ScottGu's Blog em Português

Validação do Modelo no Nível das Classes com a EF Code First e ASP.NET MVC 3


No início desta semana, a equipe de dados lançou a CTP5 da nova biblioteca Entity Framework Code-First.

No meu post há alguns dias atrás eu falei sobre algumas das melhorias introduzidas com o novo lançamento da CTP5. Suporte automático para fazer valer atributos de validação DataAnnotation em modelos foi uma das melhorias que discuti. Isto fornece uma maneira muito fácil para habilitar lógica de validação no nível da propriedade dentro da sua camada do modelo.

Você pode aplicar atributos de validação como [Required] (Obrigatório), [Range] (Limite) e [RegularExpression] (Expressão Regularar) - todos estes atributos estão incluídos no .NET 4 - em suas classes do modelo, a fim de ter certeza de que as propriedades do modelo estão em um estado válido antes de serem persistidas/salvas em um banco de dados. Você também pode criar seus próprios atributos de validação personalizados (como este validador [CreditCard] (Cartão de Crédito) muito legal - em Inglês) e fazê-los valer automaticamente através da EF Code First. Isso fornece uma maneira muito fácil para validar os valores das propriedades dos seus modelos. Mostrei alguns exemplos de código sobre esse recurso em ação no meu post anterior.

Validação do Modelo no Nível das Classes usando IValidatableObject

Atributos DataAnnotation fornecem uma maneira fácil para validar valores individuais de propriedades em suas classes do modelo. 

Várias pessoas têm perguntado - "A EF Code First também suporta uma forma de implementar métodos de validação no nível das classes em objetos do modelo, para regras de validação que precisam usar vários valores de propriedades"? Ela suporta - e uma maneira fácil de usar isso é implementando a interface IValidatableObject em suas classes do modelo.

Método IValidatableObject.Validate()

A seguir está um exemplo de como usar a interface IValidatableObject (que é nativa no .NET 4 dentro do namespace System.ComponentModel.DataAnnotations) para implementar duas regras de validação personalizadas em uma classe Product do modelo. As duas regras garantem que:

  • Novas unidades do produto não podem ser compradas se o produto está em um estado de venda descontinuada
  • Novas unidades do produto não podem ser compradas se existirem mais de 100 unidades no estoque

Vamos aplicar estas regras de negócio através da implementação da interface IValidatableObject na nossa classe de produto, implementando seu método Validate() assim:

imagem

O método IValidatableObject.Validate() pode aplicar regras de validação que abrangem várias propriedades, e pode retornar múltiplos erros de validação. Cada ValidationResult (Resultado de Validação) retornado pode fornecer tanto uma mensagem de erro, bem como uma lista opcional de nomes de propriedades que causaram a violação (o que é útil ao exibir mensagens de erro na interface do usuário).

Aplicação Automática da Validação

A EF Code-First (começando com a CTP5) agora automaticamente invoca o método Validate() quando um objeto do modelo que implementa a interface IValidatableObject é salvo. Você não precisará escrever qualquer código para fazer com que isso aconteça - esse suporte agora é ativado por padrão.

Esse novo suporte significa que o código a seguir - o qual viola uma de nossas regras de negócio acima - lançará uma exceção automaticamente (e abortará a transação), quando chamarmos o método "SaveChanges()" em nosso DbContext Northwind:

imagem

Além de reativamente tratar de exceções de validação, a EF Code First também permite que você proativamente verifique se há erros de validação. Começando com a CTP5, você pode chamar o método "GetValidationErrors()" na classe base DbContext para recuperar uma lista de erros de validação dentro dos objetos do modelo com os quais você está trabalhando. O método GetValidationErrors() retornará uma lista de todos os erros de validação - independentemente de eles serem gerados através de atributos DataAnnotation ou por uma implementação do método IValidatableObject.Validate().

A seguir está um exemplo do uso pró-ativo do método GetValidationErrors() para verificar (e tratar) os erros antes de tentar chamar o método SaveChanges():

imagem

ASP.NET MVC 3 e IValidatableObject

A ASP.NET MVC 2 incluiu suporte para aplicar e fazer valer automaticamente os atributos DataAnnotation nos objetos do modelo que são usados com a infra-estrutura de vinculação de dados (databinding) da ASP.NET MVC. A ASP.NET MVC 3 vai além e também faz valer a interface IValidatableObject. Este suporte combinado para a validação do modelo torna mais fácil exibir mensagens de erro apropriadas nos formulários quando ocorrem erros de validação. 

Para ver isso em ação, vamos considerar um formulário simples Create (Criar) que permite aos usuários criar um novo Produto:

imagem

Podemos implementar a funcionalidade Create acima usando uma classe ProductsController que tem dois métodos de ação "Create", igual ao mostrado a seguir:

imagem

O primeiro método Create() implementa uma versão da URL /Products/Create que manipula solicitações do tipo HTTP GET - e exibe o formulário HTML para preenchimento. O segundo método Create() implementa uma versão da URL /Products/Create que manipula solicitações do tipo HTTP-POST - e que leva para o servidor os dados do formulário publicado e garante que o formulário seja válido, e se ele for válido, salva os dados no banco de dados. Se houver problemas de validação, ele mostra novamente o formulário com os valores já preenchidos anteriormente. 

O modelo de visão Razor da nossa visão "Create" (que renderiza o formulário) é igual ao mostrado a seguir:

imagem

Uma das coisas agradáveis sobre a implementação do Controlador + Visão acima é que nós não escrevemos qualquer lógica de validação nesta implementação. A lógica de validação e regras de negócios são implementadas inteiramente dentro de nossa camada do modelo, e o controlador ProductsController simplesmente verifica se essas regras são válidas (chamando o método de ajuda ModelState.IsValid) para determinar se ele deve tentar salvar as alterações ou se deve exibir novamente o formulário com os erros. As chamadas para o método de ajuda Html.ValidationMessageFor() dentro da nossa visão simplesmente exibem as mensagens de erro provenientes das DataAnnotations e do método IValidatableObject.Validate() referentes ao modelo da nossa classe Product. 

Nós podemos ver o cenário descrito acima em ação através do preenchimento de dados inválidos no formulário e ao tentar submetê-los ao servidor:

imagem

Observe acima que quando clicamos no botão "Create" nós recebemos uma mensagem de erro. Isso aconteceu porque nós marcamos a caixa de seleção "Discontinued" (Descontinuado), ao mesmo tempo em que inserimos um valor em UnitsOnOrder (e assim violamos uma de nossas regras de negócio). 

Você pode perguntar - como a ASP.NET MVC sabe destacar e mostrar a mensagem de erro ao lado da caixa de texto UnitsOnOrder? Ela fez isso porque agora a ASP.NET MVC 3 honra a interface IValidatableObject quando faz a vinculação de dados do modelo e retornará as mensagens de erro a partir de falhas de validação prevenientes desta.

A regra de negócio dentro da nossa classe do modelo Product indicava que a propriedade "UnitsOnOrder" deveria ser realçada/destacada quando a regra de negócio fosse violada:

imagem

Nosso método de ajuda Html.ValidationMessageFor() sabia como exibir a mensagem de erro da regra de negócio (ao lado da caixa de texto UnitsOnOrder) em virtude do nome da propriedade que nós fornecemos:

imagem

Mantendo as coisas DRY

A ASP.NET MVC e a EF Code First permite que você mantenha a sua validação e regras de negócios em um só lugar (dentro da sua camada do modelo), evitando que elas se misturem com seus Controladores e Visões. 

Mantendo a lógica de validação na camada do modelo ajuda a garantir que não haja duplicação de validação/lógica de negócio enquanto você adiciona mais Controladores e Visões em sua aplicação. A ASP.NET MVC e a EF Code First te permitem alterar rapidamente suas regras de negócio/lógica de validação em um único lugar (dentro da sua camada do modelo) - fazendo com que todos os controladores/visões em toda a sua aplicação imediatamente reflitam essas alterações. Isso te ajuda a manter o código da sua aplicação limpo e de fácil manutenção e facilita muito a evolução e atualização da sua aplicação no futuro.

Resumo

A EF Code First (começando com a CTP5) agora possui suporte nativo tanto para DataAnnotations quanto para a interface IValidatableObject. Isso permite que você facilmente adicione regras de validação e de negócios em seus modelos, e a EF automaticamente fará valer tais regras sempre que alguém tentar persistir alterações nos objetos do modelo em um banco de dados.

A ASP.NET MVC 3 também suporta agora ambas DataAnnotations e IValidatableObject, o que torna ainda mais fácil usá-las em sua camada do modelo da EF Code First - fazendo com que os controladores/visões dentro da sua camada web automaticamente as honrem e suportem. Isto torna mais fácil construir aplicações limpas e altamente sustentáveis.

Você não tem que usar DataAnnotations ou IValidatableObject para realizar a sua validação/lógica de negócios. Você sempre pode criar sua arquitetura de validação personalizada e/ou usar outros frameworks/padrões de validação mais avançados se você quiser. Mas, para muitas aplicações este suporte nativo provavelmente será suficiente - e fornecerá uma maneira altamente produtiva para construir soluções.

Espero que ajude,

Scott

PS Além do blog, eu também estou agora utilizando o Twitter para atualizações rápidas e para compartilhar links.Siga-me em: twitter.com/ScottGu

 

Texto traduzido do post original por Leniel Macaferi.

Published Friday, December 10, 2010 3:05 AM by Leniel Macaferi
Filed under: , , ,

Comments

No Comments