Ignorar validações em Data Annotation em C# (CSharp)

Saiba como ignora validações de determinados campos de uma classe usando Data Annotation em C# (CSharp).


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

[IgnoreModelErrors()]


Imagine que em determinado ponto de nosso projeto utilizemos uma classe com vários campos e precisamos validar todos os eles utilizando Data Annotation e em outro ponto do projeto precisamos ignorar a validação de determinados campos, como fazer isto e aproveitar a classe já criada.
Este é o lugar onde o atributo IgnoreModelErrors entra. Ela nos permite especificar uma cadeia separada por vírgulas de chaves modelo e atributos para o qual queremos ignorar quaisquer erros de validação.

Veja Assim no nosso exemplo:

Exemplo da Classe

public class Categoria
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string Nome { get; set; }
    [Required]
    public string Descricao { get; set; }
}

public class Produto
{
    [Required]
    public int Id { get; set; }
    [Required]
    public string Nome { get; set; }
    [Required]
    public string Descricao { get; set; }
    [Required]
    public Categoria Categoria { get; set; }
    [Required]
    public decimal Preco { get; set; }
}


Aqui carregamos nosso form com o metodo Post utilizando o atributo [HttpPost] e adicionamos logo abaixo o atributo [IgnoreModelErrors()] utilizando os parametros separados por virgula com os campos a serem ignorados.

Exemplo da chamada da View

[HttpPost]
[IgnoreModelErrors("Categoria.Nome, Categoria.Descricao")]
public ActionResult SalvarProduto(Produto produto)
{
    if (ModelState.IsValid)
    {
        // Coloque aqui seus procedimentos, salva os dados no banco de dados por exemplo.
        return View("Successo");
    }
    else
    {
        // Coloque aqui o tratamento de seus erros.
        return View("Erro");
    }
}


Os campos Categoria.Nome e Categoria.Descricao serão ignorados na validação, note que a palavra Categoria esta sendo usada pois o modelo Categoria é um submodelo do modelo Produto, se estivéssemos tentando ignorar os atributos Nome e Descricao do modelo Produto o atributo ficaria assim :

[HttpPost]
[IgnoreModelErrors("Nome, Descricao")]


Finalmente o código parar o atributo IgnoreModelErrors:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;

public class IgnoreModelErrorsAttribute : ActionFilterAttribute
{
    private string keysString;

    public IgnoreModelErrorsAttribute(string keys)
        : base()
    {
        this.keysString = keys;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        ModelStateDictionary modelState = filterContext.Controller.ViewData.ModelState;
        string[] keyPatterns = keysString.Split(new char[] { ',' }, 
                 StringSplitOptions.RemoveEmptyEntries);
        for (int i = 0; i < keyPatterns.Length; i++)
        {
            string keyPattern = keyPatterns[i]
                .Trim()
                .Replace(@".", @"\.")
                .Replace(@"[", @"\[")
                .Replace(@"]", @"\]")
                .Replace(@"\[\]", @"\[[0-9]+\]")
                .Replace(@"*", @"[A-Za-z0-9]+");
            IEnumerable<string> matchingKeys = modelState.Keys.Where(x => Regex.IsMatch(x, keyPattern));
            foreach (string matchingKey in matchingKeys)
                modelState[matchingKey].Errors.Clear();
        }
    }
}


Comentários

Antonio Azevedo (Administrador) em 20/06/2016 22:05:27
 

Fizemos uma correção na postagem, existia um carácter invalido quando fizemos a postagem, este causava um erro e alguns usuários não estava conseguindo rodar o código. Colocamos todas as clausulas Using necessárias para a classe funcionar. Melhoramos a explicação de como ignorar um atributo, alguns usuários não estavam entendendo.