2

私は、xVal のサーバー側検証とデータ注釈を使用するアプリケーションに取り組んできました。最近、フィールドが空の場合に失敗する可能性のある複数の検証があるフィールドに対して、検証メッセージが予測できないというエラーが発生しました (たとえば、電子メール アドレスが必要ですが、有効性チェックにも失敗するなど)。

最初の検証エラーを返すだけでよいと仮定して、その目標を達成するために検証ランナーにメソッドを追加しました ( UPDATE : 正確なメソッドについては、下部の編集を参照してください)。

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

問題は、このテストの出力が非常に予測不可能であることです。成功する場合もあれば、エラーが 1 つまたは 2 つしか返されない場合もあれば、まったくエラーが返されない場合もあります。問題は、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);
    }
4

2 に答える 2

0

使用してみてください

var errors = DataAnnotationsValidationRunner.GetFirstErrors(test).ToArray();
于 2010-02-15T14:38:51.557 に答える