ModelBinder - Customizando o vinculo do Modelo com o HTML em Asp.Net MVC 4 com C# (CSharp)

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


ModelBinder

Um grande problema enfrentado quando criamos mascaras em nossas páginas é eliminar os caracteres indesejados na transferência dos dados do HTML para nosso Modelo.

Exemplo: 123.456,78 => decimal ou double

Quando é feito o vinculo de nosso HTML para nosso Modelo a conversão não é possível gerando erro e retornando uma valor nulo em nosso Modelo, o grande problema são os caracteres inconsistente encontrados ao fazer a conversão, o padrão americano utilizar ponto ao invés da virgula como separador do decimal e claro nosso ponto de milhar.

Para solucionar este problema vamos customizar este vinculo para os campos int, double e decimal.

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

CustomModelBinder.cs

/* 
 * CustomModelBinder
 * 
 *  Customizar o vinculo do Modelo com o HTML
 * 
 * Visite nossa página http://www.codigoexpresso.com.br
 * 
 */
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Mvc;


/// <summary>
/// Customizar Double
/// </summary>
public class DoubleModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (result != null )
        {
            if (bindingContext.ModelType == typeof(double) || bindingContext.ModelType == typeof(double?))
            {
                double temp;
                var attempted = result.AttemptedValue.Replace(".", "").Replace(",", ".");
                if (attempted=="")
                {
                    attempted = "0";
                }
                if (double.TryParse(
                    attempted,
                    NumberStyles.Number,
                    CultureInfo.InvariantCulture,
                    out temp)
                )
                {
                    return temp;
                }
            }
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}

/// <summary>
/// Customizar Decimal
/// </summary>

public class DecimalModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (result != null )
        {
            if (bindingContext.ModelType == typeof(decimal) || bindingContext.ModelType == typeof(decimal?))
            {
                decimal temp;
                var attempted = result.AttemptedValue.Replace(".", "").Replace(",", ".");
                if (attempted=="")
                {
                    attempted = "0";
                }
                if (decimal.TryParse(
                    attempted,
                    NumberStyles.Number,
                    CultureInfo.InvariantCulture,
                    out temp)
                )
                {
                    return temp;
                }
            }
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}


/// <summary>
/// Customizar Inteiros
/// </summary>

public class Int32ModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (result != null )
        {
            if (bindingContext.ModelType == typeof(Int32) || bindingContext.ModelType == typeof(Int32?))
            {
                Int32 temp;
                var attempted = result.AttemptedValue.Replace(".", "");
                if (attempted=="")
                {
                    attempted = "0";
                }
                if (Int32.TryParse(
                    attempted,
                    NumberStyles.Integer,
                    CultureInfo.InvariantCulture,
                    out temp)
                )
                {
                    return temp;
                }
            }
        }
        return base.BindModel(controllerContext, bindingContext);
    }
}



Agora é só registrar nosso ModelBinder em Global.asax de nosso projeto registrando no método Application_Start() nossas converções conforme exemplo abaixo.

Global.asax

 protected void Application_Start()
 {
     AreaRegistration.RegisterAllAreas();

     WebApiConfig.Register(GlobalConfiguration.Configuration);
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
     RouteConfig.RegisterRoutes(RouteTable.Routes);
     BundleConfig.RegisterBundles(BundleTable.Bundles);

     // Nossos Métodos aqui
     ModelBinders.Binders.Add(typeof(double), new DoubleModelBinder());
     ModelBinders.Binders.Add(typeof(double?), new DoubleModelBinder());
     ModelBinders.Binders.Add(typeof(int), new Int32ModelBinder());
     ModelBinders.Binders.Add(typeof(int?), new Int32ModelBinder());
     ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
     ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
 }


Pronto, agora nosso método customizado se encarrega de retirar o ponto milhar e trocar a virgula por ponto decimal ante se salvar em nosso Modelo evitando assim erros de conversão.




Links Relacionados



Comentários

Antonio Azevedo (Administrador) em 06/03/2018 00:07:41
 

Vou dar uma olhada nisto


Gabriel Padilha em 19/02/2018 12:29:31
 

Boa tarde, no meu VS ele não esta entendendo as datas, por exemplo 21/09/1996 ele não entende, ja 20/04/2018 ele entende


Antonio Azevedo (Administrador) em 09/06/2016 00:56:39
 

Fizemos uma pequena correção na classe CustomModelBinder que não permitia deixar o campo em branco.