How to change 'data-val-number' message validation in MVC while it is generated by @Html helper

You can override the message by supplying the data-val-number attribute yourself when rendering the field. This overrides the default message. This works at least with MVC 4.

@Html.EditorFor(model => model.MyNumberField, new { data_val_number="Supply an integer, dude!" })

Remember that you have to use underscore in the attribute name for Razor to accept your attribute.


What you have to do is:

Add the following code inside Application_Start() in Global.asax:

 ClientDataTypeModelValidatorProvider.ResourceClassKey = "Messages";
 DefaultModelBinder.ResourceClassKey = "Messages";

Right click your ASP.NET MVC project in VS. Select Add => Add ASP.NET Folder => App_GlobalResources.

Add a .resx file called Messages.resx in that folder.

Add these string resources in the .resx file:

FieldMustBeDate        The field {0} must be a date.
FieldMustBeNumeric     The field {0} must be a number.
PropertyValueInvalid   The value '{0}' is not valid for {1}.
PropertyValueRequired  A value is required.

Change the FieldMustBeNumeric value as you want... :)

You're done.


Check this post for more details:

Localizing Default Error Messages in ASP.NET MVC and WebForms


This is not gonna be easy. The default message is stored as an embedded resource into the System.Web.Mvc assembly and the method that is fetching is a private static method of an internal sealed inner class (System.Web.Mvc.ClientDataTypeModelValidatorProvider+NumericModelValidator.MakeErrorString). It's as if the guy at Microsoft coding this was hiding a top secret :-)

You may take a look at the following blog post which describes a possible solution. You basically need to replace the existing ClientDataTypeModelValidatorProvider with a custom one.

If you don't like the hardcore coding that you will need to do you could also replace this integer value inside your view model with a string and have a custom validation attribute on it which would do the parsing and provide a custom error message (which could even be localized).


As an alternate way around this, I applied a RegularExpression attribute to catch the invalid entry and set my message there:

[RegularExpression(@"[0-9]*$", ErrorMessage = "Please enter a valid number ")]

This slightly a hack but this seemed preferable to the complexity the other solutions presented, at least in my particular situation.

EDIT: This worked well in MVC3 but it seems that there may well be better solutions for MVC4+.


From this book on MVC 3 that I have. All you have to do is this:

public class ClientNumberValidatorProvider : ClientDataTypeModelValidatorProvider 
{ 
   public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, 
                                                          ControllerContext context) 
   { 
       bool isNumericField = base.GetValidators(metadata, context).Any(); 
       if (isNumericField) 
           yield return new ClientSideNumberValidator(metadata, context); 
   } 
} 

public class ClientSideNumberValidator : ModelValidator 
{ 
  public ClientSideNumberValidator(ModelMetadata metadata,  
      ControllerContext controllerContext) : base(metadata, controllerContext) { } 

  public override IEnumerable<ModelValidationResult> Validate(object container) 
  { 
     yield break; // Do nothing for server-side validation 
  } 

  public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
  { 
     yield return new ModelClientValidationRule { 
        ValidationType = "number", 
        ErrorMessage = string.Format(CultureInfo.CurrentCulture,  
                                     ValidationMessages.MustBeNumber,  
                                     Metadata.GetDisplayName()) 
        }; 
  } 
} 

protected void Application_Start() 
{ 
    // Leave the rest of this method unchanged 

    var existingProvider = ModelValidatorProviders.Providers 
        .Single(x => x is ClientDataTypeModelValidatorProvider); 
    ModelValidatorProviders.Providers.Remove(existingProvider); 
    ModelValidatorProviders.Providers.Add(new ClientNumberValidatorProvider()); 
} 

Notice how the ErrorMessage is yielded, you specify the current culture and the localized message is extracted from the ValidationMessages(here be culture specifics).resx resource file. If you don't need that, just replace it with your own message.