6

Problem: I am trying to manually Validate some c# objects, and the Validator is ignoring string length related validations.

Test Case: extending this example which uses the [Required] attribute, i also wanted to validate that strings were not too long, as follows.

public class Recipe
{
    //[Required]
    public string Name { get; set; }

    [MaxLength(1)] public string difficulty = "a_string_that_is_too_long";
}

public static void Main(string[] args)
{

    var recipe = new Recipe();
    var context = new ValidationContext(recipe, serviceProvider: null, items: null);
    var results = new List<ValidationResult>();

    var isValid = Validator.TryValidateObject(recipe, context, results);

    if (!isValid)
    {
        foreach (var validationResult in results)
        {
            Console.WriteLine(validationResult.ErrorMessage);
        } 
    } else {
        Console.WriteLine("is valid");
    }
}

Expected result: an error: "difficulty is too long."

Actual result: 'is valid'

other things tested:

  • the validator is working, uncommenting the [Required] results in the message "The Name field is required."
  • using [StringLength] instead (as noted at https://stackoverflow.com/a/6802739/432976 ) made no difference.
David Arno
  • 42,717
  • 16
  • 86
  • 131
Andrew Hill
  • 1,921
  • 1
  • 25
  • 31

1 Answers1

8

You need to make 2 changes to have the validation work the way you expect:

1. You have to change the difficulty field to a property.

The Validator class only validates properties, so change the difficulty definition to a property like this:

[MaxLength(1)] public string difficulty { get; set; } = "a_string_that_is_too_long";

2. Specify the validateAllProperties: true parameter to the Validator.TryValidateObject call.

The documentation for Validator.TryValidateObject is not very forthcoming about the fact that, unless you use the overload with validateAllProperties: true, only the Required attribute will be checked. So modify the call like this:

var isValid = Validator.TryValidateObject(recipe,
                                          context,
                                          results,
                                          validateAllProperties: true);
sstan
  • 35,425
  • 6
  • 48
  • 66
  • well, i guess that means even their example code at https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.stringlengthattribute(v=vs.110).aspx wouldn't work then ... (that's just a field with the attribute) – Andrew Hill Dec 01 '17 at 02:48
  • Only issue with this, is that TryValidateObject will now through an exception for other violations. Doesn't seem to "try" very hard. – maplemale Jun 24 '20 at 16:12