Question

I'm trying to manually validate an object using its Data Annotations. Our models have the annotations in a nested class, so that they don't get overwritten when we automatically update them from the database schema.

Let's say I have two classes:

public class Person
{
    [StringLength(20, MinimumLength = 3, 
       ErrorMessage = "invalid length in Person.LOGIN")]
    public string Login { get; set; }
}

[MetadataType(typeof(Car_Metadata))]
public class Car
{
    public string Brand { get; set; }

    public class Car_Metadata
    {
        [StringLength(20, MinimumLength = 3, 
             ErrorMessage = "invalid length Car.Brand")]
        public string Brand{ get; set; }
    }
}

Person has its data annotations on the same class, while Car borrows them from Car_Metadata. I can then manually validate a Person instance with the following snippet, and it works as it should:

var p = new Person { Login = "x" }; //too short, should fail

var validationResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(
    instance: p,
    validationContext: new ValidationContext(p,  
                                             serviceProvider: null, 
                                             items: null),
    validationResults: validationResults,
    validateAllProperties: true);

Assert.IsTrue(validationResults.Count() > 0);

However, the same doesn't work for Car:

var c = new Car { Brand = "x" }; //too short, should fail

var validationResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(
    instance: c,
    validationContext: new ValidationContext(c,
                                             serviceProvider: null, 
                                             items: null),
    validationResults: validationResults,
    validateAllProperties: true);

Assert.IsTrue(validationResults.Count() > 0);

I don't understand why isn't it working. Doesn't MetadataType make it so Car has the same Metadata than Car_Metadata?

Oddly enough, this works when using HTML helpers in a ASP.net MVC view, as in:

<%: Html.ValidationMessageFor(model => model.Brand) %>

... which makes me think I'm just missing something to check for "inherited" data annotations.

What am I doing wrong, or not doing?

EDIT

As suggested by Tewr, https://stackoverflow.com/a/2467282/462087 this apparently fixes it. However, i'd love to know why is it necessary to add the metadata provider explicitly again; what is [MetadataType] for then? Note that I am using that metadata from the very same project, not from a different one.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top