ModelBinder - Customizando o vinculo do Modelo com o HTML em Asp.Net MVC 4 com C# (CSharp)
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
- Atributo para validar Datas utilizando Data Annotation em Asp.Net MVC 4 com C# (CSharp).
- Atributo para validar E-mails utilizando Data Annotation em Asp.Net MVC 4 com C# (CSharp)
- Atributo para validar Horas utilizando Data Annotation em Asp.Net MVC 4 com C# (CSharp)
- Atributo para validar Números utilizando Data Annotation em Asp.Net MVC 4 com C# (CSharp)
- Atributo para validar Senhas utilizando Data Annotation em Asp.Net MVC 4 com C# (CSharp).
- Aula 04 - Validação com Data Annotation (Parte 01) em Asp.Net MVC 4 com C#(CSharp) Visual Studio 2013
- Aula 05 - Validação com Data Annotation (Parte 02) / Mascaras com JQuery-Mask em Asp.Net MVC 4 com C#(CSharp)
- Aula 06 - Validação com Data Annotation (Parte 03) / Números em Asp.Net MVC 4 com C#(CSharp)
- Aula 07 - Validação com Data Annotation (Parte 04) / Validação Remota (Attribute Remote) em Asp.Net MVC 4 com C#(CSharp)
- Aula 08 - Validação com Data Annotation (Parte 05) / Validação E-mail, Senha e Atributo Compare, Ignora Validações em Asp.Net MVC 4 com C#(CSharp)
- Data Annotation em C# (CSharp)
- Dígito verificador do CNPJ em C# (CSharp)
- Dígito verificador do CPF em C# (CSharp)
- Exemplo de Stored Procedure com tratamento de erros e transação. (SqlServer)
- Expressões Regulares [RegularExpression]
- Formatar CEP em C# (CSharp)
- Formatar CNPJ e CPF em C# (CSharp)
- Ignorar validações em Data Annotation em C# (CSharp)
- Mascaras com JQuery-Mask
- Protegendo seu site de ataques (CSRF ) com ValidateAntiForgeryToken Asp.Net MVC4 com C#(CSharp)
- Validar Modelos com Data Annotation e Windows Form Application C#(CSharp)
Comentários
Vou dar uma olhada nisto
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
Fizemos uma pequena correção na classe CustomModelBinder que não permitia deixar o campo em branco.