Search code examples
c#asp.net-mvcvalidationdata-annotationsmodelstate

How to use DataAnnotation attributes for validating a model in a console app


I'm attempting to use DataAnnotation attribute validation outside of an ASP.net MVC application. Ideally I'd like to take any model class in my console application and decorate it as follows:

private class MyExample
{
    [Required]
    public string RequiredFieldTest { get; set; }

    [StringLength(100)]
    public int StringLengthFieldTest { get; set; }

    [Range(1, 100)]
    public int RangeFieldTest { get; set; }

    [DataType(DataType.Text)]
    public object DataTypeFieldTest { get; set; }

    [MaxLength(10)]
    public string MaxLengthFieldTest { get; set; }
}

Then (pseudo) do something like this:

var item = new MyExample(); // not setting any properties, should fail validation
var isValid = item.Validate();

I found this code in a sample online:

var item = new MyExample(); // not setting any properties, should fail validation

var context = new ValidationContext(item, serviceProvider: null, items: null);
var errorResults = new List<ValidationResult>();

// carry out validation.
var isValid = Validator.TryValidateObject(item, context, errorResults);

// isValid will be FALSE

Which gives me "isValid = false" BUT it only seems to uphold the Required field and ignores the others.

The following code returns isValid = true when I expect it to return false:

var item = new MyExample() {
    RequiredFieldTest = "example text"
};

var context = new ValidationContext(item, serviceProvider: null, items: null);
var errorResults = new List<ValidationResult>();

// carry out validation.
var isValid = Validator.TryValidateObject(item, context, errorResults);

// isValid will be TRUE - not expected behavior

All other validation attempts using attributes (string length, range, max length, datatype etc) all pass as valid.

Has anyone seen this behaviour before or know why it's happening?


Solution

  • TryValidateObject by default validates only the required attribute. You can pass it a fourth parameter validateAllProperties = true, to validate the other attributes.

    if (!Validator.TryValidateObject(item, context, errorResults, true)) {
        //invalid
    }