当其他属性应用于类时,CustomValidationAttribute 不起作用

发布于 2024-10-18 20:15:02 字数 1417 浏览 9 评论 0原文

重现:

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,
                ValidationResult.Success,
                New ValidationResult("Fail!"))
    End Function
  End Class
End Class

上面的代码会抛出异常:
CustomValidationAttribute 方法“************************”在“ContactMd”类型中不存在,或者不是公共和静态的。

此异常是合理的,这是事情正在发挥作用的标志。 一旦我取消注释 Md 类中属性的 Required 属性,就不会抛出异常,这意味着验证系统不会同时验证属性类型属性和类级属性。

有什么解决办法吗?

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,
                ValidationResult.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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雾里花 2024-10-25 20:15:02

答案是,验证系统首先验证属性验证属性(在本例中为 Required 属性),并且只有在对象传递了该属性时才会继续执行 CustomValidationAttribute属性。

因此,根据上面的再现,将该行更改

Dim contact As New Contact

为类似的内容(允许实体通过属性验证):

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

将抛出预期的异常。

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.

z祗昰~ 2024-10-25 20:15:02

CustomValidationAttribute 指定的方法的签名必须是:

VB:

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

C#:

public static ValidationResult OnValidate(Contact entity, ValidationContext context)

如果验证正常,则应返回 ValidationResult.Success。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文