Atributo para validar Datas utilizando Data Annotation em Asp.Net MVC 4 com C# (CSharp).

DataBrasil, atributo customizado para validar Datas no formato dd/MM/yyyy em Asp.Net MVC 4 com C#(CSharp) e integração em javascript para o lado do cliente.


Autor : Antonio Carlos Ferreira de Azevedo
Postado em : 17/04/2016

Data Annotation Custumizado [DataBrasil()]

Nesta postagem você vai aprender a validar um campo DateTime no formato dd/MM/yyyy usando Data Annotation e jquery.validate onde será feita a validação tanto do lado do cliente como no servidor.

DataBrasilAttribute

ErrorMessage Mensagem padrão de erro.
DataRequerida True Se for obrigatória a digitação da data False se não for obrigatória a digitação da data.

Vamos criar aqui uma classe derivada da ValidationAttribute e criar nossa classe customizada para a validação no servidor.

Crie uma classe na pasta Models em seu projeto MVC com o nome de DataBrasilAttribute.cs copie e cole o código abaixo.

DataBrasilAttribute.cs

/* 
 * Atributo DataBrasil
 * 
 * Data Annotations para Validar uma Data no formato dd/MM/yyyy.
 * 
 * Visite nossa página http://www.codigoexpresso.com.br
 * 
 * by Antonio Azevedo
 *  
 * Chamada em sua Classe : 
 *   [DataBrasil(ErrorMessage="Sua mensagem de erro",DataRequerida=true/false)]
 *    
 */
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

    public class DataBrasilAttribute : ValidationAttribute, IClientValidatable
    {
        public Boolean DataRequerida { get; set; }
        public DataBrasilAttribute()
        {
            this.ErrorMessage = "Data inválida.";
            this.DataRequerida = false;
        }

        protected override ValidationResult IsValid(
            object value,
            ValidationContext validationContext)
        {
            // Verifica se valor é nulo
            if (value==null)
            {
                value = "";
            }

            // Se data não foi informada e não é requerida retorna sem validar 
            if (value.ToString() == "" && DataRequerida == false)
            {
                return ValidationResult.Success; ;
            }
           
            // Tenta converter o valor para DateTime, caso não seja possível retorna com erro.
            try
            {
                DateTime new_value = Convert.ToDateTime(value.ToString());
            }
            catch
            {
                return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
            }
           
            // Retorna com sucesso após a conversão;
            return ValidationResult.Success;
        }

        // Diretivas para validação do lado do Cliente, implementação com jquery.validate
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
            ModelMetadata metadata,
            ControllerContext context)
        {
            var Rule = new ModelClientValidationRule
            {
                ValidationType = "databrasil",
                ErrorMessage = this.FormatErrorMessage(metadata.PropertyName)

            };

            Rule.ValidationParameters["datarequerida"] = DataRequerida;
            yield return Rule;
        }
    }

Agora vamos cuidar da validação do lado no cliente, ou seja, no navegado do cliente.
O MVC se encarrega de transportar os parametros para nosso HTML mas mesmo assim temos que fazer toda a validação em JavaScript novamente.

Crie uma arquivo JavaScript na pasta Scripts de seu projeto MVC, de o nome de CustomValidacoes.js copie e cole o código abaixo.

CustomValidacoes.js

// Adicionamos o método date para sobrepor o método padrão e atribuindo sempre um retorno verdadeiro para garantir 
// que o JQuery não vai tratar as data exibindo mensagens indesejadas. 
$.validator.addMethod('date',
   function (value, element) {
        return true;
});

// Aqui adicionamos os métodos respeitando os nomes gerado em nossa classe atributo
// os nomes devem estar em caixa baixa tanto na integração como aqui no JavaScript (Nome atributo, parametro)
$.validator.unobtrusive.adapters.addSingleVal("databrasil", "datarequerida");

//Aqui temos a funcao que Valida do lado do cliente as datas digitadas utilizando uma expressão regular
$.validator.addMethod('databrasil',
function (value, element, datarequerida) {

    // Verificamos se o valor foi digitado
    if (value.length == 0) {
        // Se a data é requerida retorna erro senão retorna com sucesso
        if (datarequerida.toString() == 'True') {
            return false;
        }
        else {
            return true;
        }
    }

    /// Expressão Regular para tratar datas, dd/MM/yyyy, validando também ano Bisexto.
    var expReg = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/;

    // Valida a expressão, se for compatível vai retornar validando o campo, caso contrario exibe a mensagem de erro informada no atributo;
    return value.match(expReg);
});

Este arquivo deve ser carregado após o carregamento do jquery.validate, estamos sobrepondo o método date do JQuery.validate para evitar que seja feita a validação padrão.

Exemplo de como utilizar o atributo em sua classe.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using SeuProjeto.Models;

namespace AspNetMVC_Aula.Models
{
    public class ModAluno
    {
       [DataBrasil(ErrorMessage = "Data inválida", DataRequerida = false)]
       public DateTime? Data { get; set; }
    }
}




Comentários

Antonio Azevedo (Administrador) em 03/05/2016 21:54:48
 

Fizemos uma pequena correção no JavaScript da Validação, alguns navegadores se perdem ao tratar variáveis Boolean, sendo assim estamos convertendo para string corrigindo assim o problema.
Correção => if (datarequerida.toString() == 'True')