views:

93

answers:

1

I have this property on a class:

public virtual decimal? Number { get; set; }

When I'm using it on a form, MVC validates it automatically. If the user enters a letter, naturally an error is returned:

"The value 'D' is not valid for Number."

How do I change such error message or even control that behavior? I'm not finding the related attribute or something like that.

Thank you!

A: 

It is actually not a message that derives from model validation. The message is added to the model state when the model binder is unable to convert an input value to the value type of the bound property. This may for example occur when the bound property is an integer and the user entered a non-numeric character in the input field of that property.

To override the message you'll unfortunately have to do it the "hard" way, i.e. extend the DefaultModelBinder class and override the SetProperty method. Here is an example:

public class MyModelBinder: DefaultModelBinder
{
    public MyModelBinder()
    {
    }

    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
    {
        string key = bindingContext.ModelName + "." + propertyDescriptor.Name;
        if (bindingContext.ModelState[key] != null)
        {

            foreach (ModelError error in bindingContext.ModelState[key].Errors)
            {
                if (IsFormatException(error.Exception))
                {
                    bindingContext.ModelState[key].Errors.Remove(error);
                    bindingContext.ModelState[key].Errors.Add(string.Format("My message for {0}.", propertyDescriptor.DisplayName));
                    break;
                }
            }
        }
        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
    }

    private bool IsFormatException(Exception e)
    {
        while (e != null)
        {
            if (e is FormatException)
            {
                return true;
            }
            e = e.InnerException;
        }
        return false;
    }
}
Slaktad