gpt4 book ai didi

asp.net-mvc - MVC 4自定义验证属性在服务器端触发两次

转载 作者:行者123 更新时间:2023-12-02 21:28:06 25 4
gpt4 key购买 nike

我正在使用继承自RequiredAttribute的自定义验证requiredconditional来有条件地要求某些字段。除了一次情况外,这在任何地方都很有效,我无法弄清楚发生了什么。它为模型中的一个属性调用 IsValid 方法两次(客户端验证工作正常)该模型有 2 个属性使用此属性,但只有一个存在问题。起初我认为这是因为我的条件之一是一个复选框,它同时回发选中的值和隐藏的值,但我尝试使用单选按钮,甚至隐藏值,但在所有情况下都有相同的结果。这是我的观点(为了测试而简化):

@ModelType List(Of eLADNETBusiness.AdditionalInterest)

@Code
ViewData("Title") = "Bind Coverage Entry"
End Code

<h2>Bind Coverage Entry</h2>
@Using Html.BeginForm()
@Html.AntiForgeryToken()
@Html.Hidden("hullValue", ViewBag.HullValue)
Dim currentCount As Integer = 0
@For count As Integer = 0 To Model.Count - 1
currentCount = count
@<div class="editor-label">
@Html.LabelFor(Function(model) model(currentCount).LienholderAmount)
</div>
@<div class="editor-field">
@Html.EditorFor(Function(model) model(currentCount).LienholderAmount)
@Html.ValidationMessageFor(Function(model) model(currentCount).LienholderAmount)
</div>
@<div>
@Html.EditorFor(Function(model) model(currentCount).Lienholder90Percent)
</div>
Next
@<p>
<input type="submit" value="Continue" />
</p>

End Using

这是我的模型(为了测试而简化):

<DataContract()> _
Public Class AdditionalInterest
<DataMember()> _
Public Property ID As Integer = 0

<RequiredConditional("Lienholder90Percent", False, ErrorMessage:="Enter Breach of Warranty lienamount or select 90 percent of insured value")> _
<Display(Name:="Lienholder Amount")> _
<DataMember()> _
Public Property LienholderAmount As Nullable(Of Integer)

<DataMember()> _
Public Property Lienholder90Percent As Boolean

下课

以及我的必需条件属性:

Imports System.Collections.Generic
Imports System.Linq
Imports System.ComponentModel.DataAnnotations
Imports System.Web.Mvc
Imports System.Collections
Imports System.Text

Public Class RequiredConditional
Inherits RequiredAttribute
Implements IClientValidatable

Private Property PropertyNames() As String()
Private Property DesiredValues() As Object()

Public Sub New(comparePropertyNames As String(), comparePropertyDesiredValues As Object())
PropertyNames = comparePropertyNames
DesiredValues = comparePropertyDesiredValues
End Sub

Public Sub New(comparePropertyNames As String, comparePropertyDesiredValues As Object)
PropertyNames = New String() {comparePropertyNames}
DesiredValues = New String() {comparePropertyDesiredValues}
End Sub

Protected Overrides Function IsValid(value As Object, context As ValidationContext) As ValidationResult
Dim instance As Object = context.ObjectInstance
Dim type As Type = instance.GetType()
Dim propertyvalue As Object
Dim trueConditions As Integer = 0
For count As Integer = 0 To PropertyNames.Count - 1
propertyvalue = type.GetProperty(PropertyNames(count)).GetValue(instance, Nothing)
If Not propertyvalue Is Nothing Then
If DesiredValues.Count >= count + 1 Then
If propertyvalue.ToString() = DesiredValues(count).ToString() Then
trueConditions += 1
End If
End If
End If
Next
'if all conditions are met, validate value
If trueConditions = PropertyNames.Count And trueConditions = DesiredValues.Count Then
Dim result As ValidationResult = MyBase.IsValid(value, context)
Return result
End If

Return ValidationResult.Success
End Function

Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, context As System.Web.Mvc.ControllerContext) As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.ModelClientValidationRule) _
Implements System.Web.Mvc.IClientValidatable.GetClientValidationRules

Dim results As New List(Of ModelClientValidationRule)
Dim rule = New ModelClientValidationRule With {.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), .ValidationType = "requiredif"}

Dim depProp As String = String.Empty

Dim sbProp As New StringBuilder()
Dim sbTarget As New StringBuilder()
Dim helper As New ValidationHelper

For count As Integer = 0 To PropertyNames.Count - 1
Dim prop As String = PropertyNames(count)
depProp = helper.BuildDependentPropertyName(metadata, TryCast(context, ViewContext), prop)
sbProp.AppendFormat("|{0}", depProp)

Dim targetValue As String = String.Empty
If DesiredValues.Count >= count + 1 Then
targetValue = (If(DesiredValues(count), "")).ToString()
End If

If DesiredValues(count).GetType() = GetType(Boolean) Then
targetValue = DesiredValues(count).ToString.ToLower
End If

sbTarget.AppendFormat("|{0}", targetValue)

Next

rule.ValidationParameters.Add("dependentproperty", sbProp.ToString().TrimStart("|"))
rule.ValidationParameters.Add("targetvalue", sbTarget.ToString().TrimStart("|"))


results.Add(rule)
Return results

End Function

End Class

因此,当我单击“提交”并调试到 requiredconditional 属性时,lienholderamount 属性会命中 IsValid 两次。第一次命中时,Lienholder90Percent 的值是 False,即使在模型中它是 true 并且在表单上也是 true(并通过了客户端验证),因此此时验证失败。然后再次点击,Lienholder90Percent 为 True(这是正确的)并通过验证。但由于第一次失败,它仍然失败并显示错误消息。您会注意到该模型是一个列表,但出于测试目的,我只发送一个,但仍然得到相同的结果。无法弄清楚为什么这种情况只发生在这一处特性上。希望这是一件简单的事情,我只是看不到。我花了一整天的时间试图弄清楚这一点。就像我说的,我经常使用这个属性并且效果很好。找不到此案例的差异。

最佳答案

继承自ValidationAttribute,而不是RequiredAttribute

RequiredAttribute 的 IsValid 在属性填充后立即调用,而 ValidationAttribute 的 IsValid 在整个模型填充后调用(这对于更复杂的验证来说是有意义的)。

关于asp.net-mvc - MVC 4自定义验证属性在服务器端触发两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23024097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com