"Filtering" a collection before starting a Linq query on it
I´m working on some validation code and having some issues with my Linq code.
What I have is 开发者_如何学运维a class that validates on a particular attribute (ValidationAttribute). That all works fine, ie the validation works with a class that has some properties decorated with that attribute (or subclasses of it).
What I now want to accomplish is to tell my "validator" class to ignore all properties that are marked with a certain other attribute (let´s call that IgnoreAttribute).
So my question is, how do I first find all the properties with the validation attribute (which I have code for already) but first "filter" that collection to ignore the properties that have the ignore attribute (or actually a List collection).
The code for the validation looks like:
from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>().
where attribute.IsValid(prop.GetValue(instance)) == false
select new ...etc
I want this code to ignore all attributes contained in a List that I have in the class, ie some sort of filtering on the original set...
Any ideas?
UPDATE:
I guess my question is really this: If I have a class that has its properties decorated with attributes like:
class MyClass
[Required]
public string MyProp { get; set; }
[Required]
[Ignore]
public string MyProp2 { get; set; }
How do I find all the properties that have the validation attribute (required inherits that)) but not the ignore attribute? Although I really wan´t it to ignore a list of attributes and not only the ignore attribute.
Not Any?
from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
where !prop.Attributes.OfType<IgnoreAttribute>().Any()
from attribute in prop.Attributes.OfType<ValidationAttribute>().
where attribute.IsValid(prop.GetValue(instance)) == false
select new ...etc
Do you need the PropertyDescriptor
flexible model? Pretty easy with reflection:
var filtered = instance.GetType().GetProperties()
.Where(prop => !Attribute.IsDefined(prop, typeof(IgnoreAttribute)));
Or to do the whole thing:
var invalid = from prop in instance.GetType().GetProperties()
where !Attribute.IsDefined(prop, typeof(IgnoreAttribute))
let valAttribs = Attribute.GetCustomAttributes(
prop, typeof(ValidationAttribute))
where valAttribs != null && valAttribs.Length > 0
let value = prop.GetValue(instance, null)
from ValidationAttribute valAttrib in valAttribs
where !valAttrib.IsValid(value)
select new {};
精彩评论