开发者

CustomValidationAttribute doesn't work when other attributes are applied to the class

开发者 https://www.devze.com 2023-02-13 11:27 出处:网络
Reproduction: Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations Module Module1

Reproduction:

Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
Module Module1

  Sub Main()
    Dim type = GetType(Contact)
    TypeDescriptor.AddProviderTransparent(
      New AssociatedMetadataTypeTypeDescriptionProvider(type), type)


    Dim contact As New Contact
    Dim context As New ValidationContext(contact, Nothing, Nothing)
    Dim errors As New List(Of ValidationResult)
    Dim result = Validator.TryValidateObject(contact, context, errors, True)
  End Sub
End Module

<CustomValidation(GetType(Contact.ContactMd), "*********************")>
<MetadataType(GetType(Contact.ContactMd))>
Public Class Contact

  Public Property Email As String
  Public Property EmailRepeat As String

  Public Class ContactMd

    '<Required()>
    Public Property Email
    '<Required()>
    Public Property EmailRepeat

    Public Shared Function ValidateEmails(ByVal contact As Contact) _
        As ValidationResult
      Return If(contact.Email = contact.EmailRepeat,
                ValidationRe开发者_开发知识库sult.Success,
                New ValidationResult("Fail!"))
    End Function
  End Class
End Class

The above code will throw an exception:

The CustomValidationAttribute method '*********************' does not exist in type 'ContactMd' or is not public and static.

This exception is justified and it's a sign that things are working. Once I uncomment the Required attributes on the properties in the Md class, the exception will not be throw, which means, the validation system doesn't validate for both property-typed attributes and class-level attributes.

Any workaround?


The answer is, that the validation system validates the property validation attributes first (the Required attributes in this case), and will only proceed to the CustomValidationAttribute if the object passed the property attributes.

So per the reproduction above, changing the line

Dim contact As New Contact

to something like (allowing the enitity to pass the property validation):

Dim contact As New Contact With { .Email = "*", .EmailRepeat = "*" }

Will throw the expected exception.


The signature for the method specified by the CustomValidationAttribute must be:

VB:

Public Shared Function OnValidate(
    entity As Contact, context As ValidationContext) As ValidationResult

C#:

public static ValidationResult OnValidate(Contact entity, ValidationContext context)

If the validation is OK, it should return ValidationResult.Success.

0

精彩评论

暂无评论...
验证码 换一张
取 消