1
votes

I'm struggling with ASP .NET MVC 3 unobtrusive validation. My simple model contains of this field:

[Display(Name = "Starting Amount")]
[Required(ErrorMessage = "Starting Amount is required.")]
public decimal? StartAmount { get; set; }

I'm using some jQuery plugin that automatically formats currency and numbers, so StartAmount field is prefixed with a dollar sign ($). Client side validation on this field should get rid of this dollar sign, so I extended jQuery validator like this:

$.validator.methods.number = function (value, element) {
        return true;
    }

This fixed the problem of the dollar sign, but now validation fails for Required rule. When input field is empty, there is no "The Starting Amount field is required." message displayed. Any ideas what I'm doing wrong?

1

1 Answers

1
votes

Do not make any changes to the jQuery validator. What you need to do is to define a custom model binder for the type decimal like this:

public class DecimalModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;

        if (valueResult != null && !string.IsNullOrEmpty(valueResult.AttemptedValue))
        {
            try
            {
                actualValue = decimal.Parse(valueResult.AttemptedValue, NumberStyles.Currency, CultureInfo.CurrentCulture);
            }
            catch (FormatException e)
            {
                modelState.Errors.Add(e);
            }

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

        return actualValue;
    }
}

Then, in the Application_Start event of your Global.asax, register your custom model binder like this:

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

You can read more about NumberStyles here: NumberStyles Enumeration