1

I can't seem to ding a way to override the default behaviour of the MVC validation for numeric fields.

I've created a default MVC4 project to represent my problem.

The model (The default MVC 4 constructs for you, plus two properties "Age" and "Date"):

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }

    public DateTime Date { get; set; }

    public int Age { get; set; }

So by default MVC validates the two fields I've created and I'm getting the following validation messages: "The field "Age" is required" and "The field "Date" is required"

Now what i am trying to achieve is forcing my application to ignore the default numeric validation (I'm doing this on client side and it's impossible for a user to enter an invalid value). I have tried forcing MVC not to add default "required" attributes for non-nullable properties:

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

This gave me some progress. Now it does not do "Required" validation, but posting of a form results two identical validation messages: "A value is required".

I could not achieve anything beyond this point. I've tried removing the ClientDataTypeModelValidatorProvider

        foreach (ModelValidatorProvider prov in ModelValidatorProviders.Providers)
        {
            if (prov.GetType().Equals(typeof(ClientDataTypeModelValidatorProvider)))
            {
                break;
            }
        }

as well as all providers altogether

ModelValidatorProviders.Providers.Clear();

without any success.

I've also tried to overload some of the default attributes MVC is using in DataAnnotationsModelValidatorProvider, however this gave me no results.

So there is a couple of question I'd like to ask about this situation:

  1. Is it possible to force MVC not to do default validation on server side for non-nullable data types? If possible how?
  2. Is it possible to change the default behaviour of validation described in the question no.1? If possible - how?
  3. Is it possible to force MVC to use my custom validator / validation attribute instead of this custom one? If possible - how?

Also a note: I do not want to write my attribute that does validation for me and put it on every single property it should do validation on. I am looking for a solution, which would allow me to define the rules on how the default validation should be done.

Thanks in advance or any suggestions.

2
  • Make the Date and Age as nullable datetime and int respectively Commented Oct 29, 2013 at 11:53
  • I don't want to do that for a number of reasons. Data types have to be not nullable. Commented Oct 29, 2013 at 12:18

1 Answer 1

1

Create your own ModelBinder for int. Then make that binder return 0 on error.

public class IntModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try
        {
            actualValue = Convert.ToInt32(valueResult.AttemptedValue,
                System.Globalization.CultureInfo.InvariantCulture);
        }
        catch (FormatException e)
        {
            //Uncomment for default error
            //modelState.Errors.Add(e);
            actualValue = 0;
        }

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

And in Global.asax Application_Start():

ModelBinders.Binders.Add(typeof(int), new IntModelBinder());
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.