gpt4 book ai didi

c# - 使用 PropertyDescriptor 确定属性是否为复杂对象

转载 作者:太空宇宙 更新时间:2023-11-03 13:18:02 25 4
gpt4 key购买 nike

我正在尝试在 WCF 服务中进行一些验证,为此我正在使用 WCFDataAnnotations我通过 this post 找到的

问题是它不能递归验证,所以对于嵌套对象它不起作用。这么说吧

[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; }

}

它不会准确地获得所需的 childModel RequiredValue。

所以我查看了那个 dll 的源代码并试图让它工作。实际代码是

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 }
);
}
}

所以我想把它改成这样

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;
}

目的是检查是否有任何属性是复杂的,如果是复杂的则递归地验证自身,但我不确定如何检查给定的“props”是否已转换为 TypeDescriptors。

谢谢

最佳答案

在我看来,下面的代码应该可以解决问题:

public IEnumerable<ValidationResult> Validate(object input)
{
return ValidateWithState(input, new HashSet<object>());
}

private IEnumerable<ValidationResult> ValidateWithState(object input, HashSet<object> traversedInputs)
{
if (input == null || traversedInputs.Contains(input))
{
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>())
{
if (!att.IsValid(prop.GetValue(input)))
{
validationResults.Add(new ValidationResult(
att.FormatErrorMessage(string.Empty),
new[] { prop.Name }
));
}

traversedInputs.Add(input);

if (prop.PropertyType.IsClass || prop.PropertyType.IsInterface))
{
validationResults.AddRange(ValidateWithState(prop.GetValue(input), traversedInputs));
}
}

return validationResults;
}

可能不是最优雅的解决方案,但我认为它会奏效。

关于c# - 使用 PropertyDescriptor 确定属性是否为复杂对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25388701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com