如何确定不可预测的LINQ查询结果的来源?

时间:2010-02-15 12:34:33

标签: asp.net-mvc linq nunit xval

我一直致力于使用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);
    }

2 个答案:

答案 0 :(得分:2)

摆脱Take(1)。我怀疑空字符串正在通过Required测试。如果您发生而不是长度验证器,则测试通过。

答案 1 :(得分:0)

尝试使用

var errors = DataAnnotationsValidationRunner.GetFirstErrors(test).ToArray();