我一直致力于使用xVal服务器端验证和数据注释的应用程序。我们最近遇到了错误,其中验证消息对于具有多个验证的字段是不可预测的,如果字段为空(例如,需要电子邮件地址,但也未通过有效性检查),则可能会失败。
假设我需要返回第一个验证错误,我向验证运行器添加了一个方法来实现该目标(更新:请参见底部的编辑以获取确切的方法):
public static IEnumerable<ErrorInfo> GetFirstErrors<T>(object instance) where T : ValidationAttribute
{
return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<T>().Take(1)
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
}
我还设置了一个简单的测试方法来验证NUnit:
private class FirstErrorValidationTest
{
[RequiredValueValidator(ErrorMessage = "This field is required"), StringLength(50)]
public string FirstName { get; set; }
[RequiredValueValidator(ErrorMessage = "This field is required"), StringLength(50)]
public string LastName { get; set; }
[RequiredValueValidator(ErrorMessage = "This field is required"), EmailAddressValidator, StringLength(50)]
public string EmailAddress { get; set; }
}
[Test]
public void Assert_GetFirstErrors_Gets_First_Listed_Validation_Attribute_Error_Messages()
{
FirstErrorValidationTest test = new FirstErrorValidationTest()
{
FirstName = "",
LastName = "",
EmailAddress = ""
};
var errors = DataAnnotationsValidationRunner.GetFirstErrors(test);
Assert.AreEqual(3, errors.Count());
foreach (var error in errors)
Assert.IsTrue(error.ErrorMessage.Contains("required"));
}
问题是这个测试的输出是高度不可预测的。有时它会通过,有时它只返回一两个错误,有时甚至根本没有。我的LINQ查询,我的测试或两者都存在问题吗?
编辑:以稍微不同的方式粘贴的重点;这是实际被击中的那个:
public static IEnumerable<ErrorInfo> GetFirstErrors(object instance)
{
return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>().Take(1)
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
}
答案 0 :(得分:2)
摆脱Take(1)
。我怀疑空字符串正在通过Required
测试。如果您发生而不是长度验证器,则测试通过。
答案 1 :(得分:0)
尝试使用
var errors = DataAnnotationsValidationRunner.GetFirstErrors(test).ToArray();