I'm trying to do some validation in a WCF service, and for that I'm using WCFDataAnnotations which I found through this post
Problem is that it doesn't validate recursively, so for a nested object it doesn't work. Let's say this
[DataContract]
public class Model
{
[DataMember]
[Required(ErrorMessage = "RequiredOne is required")]
public string RequiredOne { get; set; }
[DataMember]
[StringLength(10, ErrorMessage = "Not Required should be at most 10 characters long")]
public string NotRequired { get; set; }
[DataMember]
[Required(ErrorMessage = "ChildModel is required")]
public ChildModel ChildModel { get; set; }
}
[DataContract]
public class ChildModel
{
[DataMember]
[Required(ErrorMessage = "RequiredValue is required")]
public string RequiredValue { get; set; }
[DataMember]
public string NotRequiredValue { get; set; }
}
It won't get the childModel RequiredValue as precisely that, required.
So I was taking a look into the source code of that dll and trying to make it work. The actual code is
public class DataAnnotationsObjectValidator : IObjectValidator
{
public IEnumerable<ValidationResult> Validate(object input)
{
if (input == null) return Enumerable.Empty<ValidationResult>();
return from property in TypeDescriptor.GetProperties(input).Cast<PropertyDescriptor>()
from attribute in property.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(property.GetValue(input))
select new ValidationResult
(
attribute.FormatErrorMessage(string.Empty),
new[] { property.Name }
);
}
}
So my thought are changing this to something like this
public IEnumerable<ValidationResult> Validate(object input)
{
if (input == null) return Enumerable.Empty<ValidationResult>();
var validationResults = new List<ValidationResult>();
foreach (var prop in TypeDescriptor.GetProperties(input).Cast<PropertyDescriptor>())
{
foreach (var att in prop.Attributes.OfType<ValidationAttribute>())
{
//This doesn't work, it's one of the several
//attempts I've made
if (prop.ComponentType.IsClass)
Validate(prop.ComponentType);
if (!att.IsValid(prop.GetValue(input)))
{
validationResults.Add(new ValidationResult(
att.FormatErrorMessage(string.Empty),
new[] { prop.Name }
));
}
}
}
return validationResults;
}
The intention is check if any of the properties is a complex one and if it's the case validate itself recursively, but I'm not sure how to check that given the "props" are casted to TypeDescriptors.
Thanks
Seems to me that the following code should do the trick:
Might not be the most elegant solution, but i think it'll work.
Now I am able to validate public List ChildModel. With Reference to DevTrends.WCFDataAnnotations, ValidatingParameterInspector.cs class, (http://wcfdataannotations.codeplex.com/SourceControl/latest#DevTrends.WCFDataAnnotations/ValidatingParameterInspector.cs).
I am sure ValidateCollection can be further modified to check collection within ChildModel.Currently it check upto one level only .
My Example,
Original code do not validate List,So I created one more function ValidateCollection Manipulated the object[] inputs to extract each ChildModel class and put it back in object[] inputs like model class reside in object[] inputs.