I have a bunch of forms where currency values are entered and I want them to be able to enter "$1,234.56". By default, the model binders won't parse that into a decimal.
What I am thinking of doing is creating a custom model binder the inherits DefaultModelBinder, override the BindProperty method, check if the property descriptor type is decimal and if it is, just strip out the $ and , from the values.
Is this the best approach?
Code:
public class CustomModelBinder : DefaultModelBinder
{
protected override void BindProperty( ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor )
{
if( propertyDescriptor.PropertyType == typeof( decimal ) || propertyDescriptor.PropertyType == typeof( decimal? ) )
{
var newValue = Regex.Replace( bindingContext.ValueProvider[propertyDescriptor.Name].AttemptedValue, @"[$,]", "", RegexOptions.Compiled );
bindingContext.ValueProvider[propertyDescriptor.Name] = new ValueProviderResult( newValue, newValue, bindingContext.ValueProvider[propertyDescriptor.Name].Culture );
}
base.BindProperty( controllerContext, bindingContext, propertyDescriptor );
}
}
Update
This is what I ended up doing:
public class CustomModelBinder : DataAnnotationsModelBinder
{
protected override void BindProperty( ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor )
{
if( propertyDescriptor.PropertyType == typeof( decimal ) || propertyDescriptor.PropertyType == typeof( decimal? ) )
{
decimal newValue;
decimal.TryParse( bindingContext.ValueProvider[propertyDescriptor.Name].AttemptedValue, NumberStyles.Currency, null, out newValue );
bindingContext.ValueProvider[propertyDescriptor.Name] = new ValueProviderResult( newValue, newValue.ToString(), bindingContext.ValueProvider[propertyDescriptor.Name].Culture );
}
base.BindProperty( controllerContext, bindingContext, propertyDescriptor );
}
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…