By default, MVC model binder validates each object before assigning properties, including each object in a list.
However if we want to implement a custom validation attribute (using DataAnnotations), and use Validator.TryValidateObject mehtod, this can get bit tricky, since it does not recursively validate 'properties of objects returned by properties'.
What is means it assuming I have class A defined as:
And class B defined as:
Then calling Validator.TryValidateObject on an object of will validate if myPropertyList inside the object has a value, but it will not validate if each object in the myPropertyList has a name assigned.
There are several solutions to this problem.
1) For an IEnumarable use custom validation attribute IsValid method convert myPropertyList to a IEnumarable then enumerate through each object in the list and call Validator.TryValidateObject method on the object, finally combine all the result to get the error messages. This is explained at https://stackoverflow.com/questions/51523346/validating-lists-in-c-sharp
2) TryValidateObject method would also ignore validation attribute of name in class A if it is not a list, but a single object
e.g. given that I have
TryValidateObject again won't validate that name is not empty if called on an object of class D. In such a situation a custom validation attribute can be assigned to myProperty which can do this task and aggregate the results. This is explained at http://www.technofattie.com/2011/10/05/recursive-validation-using-dataannotations.html
3) Implement IValidatableObject interface at the top level class and iterate through each property recursively to validate it.
4) There is also in interesting article for client side validation at https://stackoverflow.com/questions/23337170/data-validation-for-every-item-in-a-list-of-my-viewmodel
However if we want to implement a custom validation attribute (using DataAnnotations), and use Validator.TryValidateObject mehtod, this can get bit tricky, since it does not recursively validate 'properties of objects returned by properties'.
What is means it assuming I have class A defined as:
class A
{
[Required]
public string name;
}
And class B defined as:
class B
{
[Required]
public List<A> myPropertyList;
}
Then calling Validator.TryValidateObject on an object of will validate if myPropertyList inside the object has a value, but it will not validate if each object in the myPropertyList has a name assigned.
There are several solutions to this problem.
1) For an IEnumarable use custom validation attribute IsValid method convert myPropertyList to a IEnumarable then enumerate through each object in the list and call Validator.TryValidateObject method on the object, finally combine all the result to get the error messages. This is explained at https://stackoverflow.com/questions/51523346/validating-lists-in-c-sharp
2) TryValidateObject method would also ignore validation attribute of name in class A if it is not a list, but a single object
e.g. given that I have
class C
{
[Required]
public string name;
}
class D
{
[Required]
public A myProperty;
}
e.g. given that I have e.g. given that I have e.g. given that I have e.g. given that I have
TryValidateObject again won't validate that name is not empty if called on an object of class D. In such a situation a custom validation attribute can be assigned to myProperty which can do this task and aggregate the results. This is explained at http://www.technofattie.com/2011/10/05/recursive-validation-using-dataannotations.html
3) Implement IValidatableObject interface at the top level class and iterate through each property recursively to validate it.
4) There is also in interesting article for client side validation at https://stackoverflow.com/questions/23337170/data-validation-for-every-item-in-a-list-of-my-viewmodel
No comments:
Post a Comment