Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET MVC 3 Custom Decimal? Model Binder

In my model, I have the following decimal? property:

public decimal? Budget { get; set; }

I realize that I need a custom model binder for decimals which Haack provided at the following link: http://haacked.com/archive/2011/03/19/fixing-binding-to-decimals.aspx.

I have modified his code so that if the value being passed in does contain a currency symbol and/or comma then I strip it and then try to convert it to a decimal. This works but being that my property is a nullable decimal type, I also want it to accept nothing and move along its merry way inserting a null into that column in my database. Right now it inserts a 0.00. I know I'm missing something in my code but am having a brain freeze.

Here's the binder code:

 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    ModelState modelState = new ModelState { Value = valueResult };
    object actualValue = null;
    object newValue = null;
    try
    {
        if (!string.IsNullOrEmpty(valueResult.AttemptedValue))
        {
            newValue = valueResult.AttemptedValue.Replace("$", "").Replace(",", "");
        }

        actualValue = Convert.ToDecimal(newValue, CultureInfo.CurrentCulture);
    }
    catch (FormatException e)
    {
        modelState.Errors.Add(e);
    }

    bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
    return actualValue;
}

Again, the goal is to have decimal? act like it usually does but if there is a value which contains a currency symbol and/or comma and it can be converted to a decimal then to return that.

Thanks

like image 339
Mike Avatar asked May 24 '11 14:05

Mike


1 Answers

You're probably better off to utilize the built in support for handling NumberStyles. By doing this you can account for more than just the common dollar sign but can also handle Pounds, Yen, etc...

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    ValueProviderResult valueResult = bindingContext.ValueProvider
        .GetValue(bindingContext.ModelName);
    ModelState modelState = new ModelState { Value = valueResult };
    object actualValue = null;
    try
    {
        if(!string.IsNullOrWhiteSpace(valueResult.AttemptedValue))
            actualValue = Decimal.Parse(valueResult.AttemptedValue, NumberStyles.Currency, CultureInfo.CurrentCulture);
    }
    catch (FormatException e)
    {
        modelState.Errors.Add(e);
    }

    bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
    return actualValue;
}
like image 135
Nick Albrecht Avatar answered Oct 21 '22 02:10

Nick Albrecht