编辑:此假设您正在使用MVC 3。不幸的是,我的代码是VB.NET,因为这是我在工作中必须使用的。
为了使所有内容与新的非侵入式验证完美配合,您需要执行一些操作。几周前,我已经完成了这些操作。
首先,创建一个自定义属性类,该类继承自ValidationAttribute
。下面是一个简单的RequiredIf属性类:
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)> _
Public NotInheritable Class RequiredIfAttribute
Inherits ValidationAttribute
Private Const _defaultErrorMessage As String = "'{0}' is required."
Private ReadOnly _dependentProperty As String
Private ReadOnly _targetValues As Object()
Public Sub New(dependentProperty As String, targetValues As Object())
MyBase.New(_defaultErrorMessage)
_dependentProperty = dependentProperty
_targetValues = targetValues
End Sub
Public Sub New(dependentProperty As String, targetValues As Object(), errorMessage As String)
MyBase.New(errorMessage)
_dependentProperty = dependentProperty
_targetValues = targetValues
End Sub
Public ReadOnly Property DependentProperty() As String
Get
Return _dependentProperty
End Get
End Property
Public ReadOnly Property TargetValues() As Object()
Get
Return _targetValues
End Get
End Property
Public Overrides Function FormatErrorMessage(name As String) As String
Return String.Format(Globalization.CultureInfo.CurrentUICulture, ErrorMessageString, name)
End Function
Protected Overrides Function IsValid(value As Object, context As ValidationContext) As ValidationResult
' find the other property we need to compare with using reflection
Dim propertyValue = context.ObjectType.GetProperty(DependentProperty).GetValue(context.ObjectInstance, Nothing).ToString()
Dim match = TargetValues.SingleOrDefault(Function(t) t.ToString().ToLower() = propertyValue.ToLower())
If match IsNot Nothing AndAlso value Is Nothing Then
Return New ValidationResult(FormatErrorMessage(context.DisplayName))
End If
Return Nothing
End Function
End Class
接下来,您需要实现一个验证器类。该类负责让MVC知道客户端验证规则,这些规则是必需的,以便无侵入式验证库能够正常工作。
Public Class RequiredIfValidator
Inherits DataAnnotationsModelValidator(Of RequiredIfAttribute)
Public Sub New(metaData As ModelMetadata, context As ControllerContext, attribute As RequiredIfAttribute)
MyBase.New(metaData, context, attribute)
End Sub
Public Overrides Function GetClientValidationRules() As IEnumerable(Of ModelClientValidationRule)
Dim rule As New ModelClientValidationRule() With {.ErrorMessage = ErrorMessage,
.ValidationType = "requiredif"}
rule.ValidationParameters("dependentproperty") = Attribute.DependentProperty.Replace("."c, HtmlHelper.IdAttributeDotReplacement)
Dim first As Boolean = True
Dim arrayString As New StringBuilder()
For Each param In Attribute.TargetValues
If first Then
first = False
Else
arrayString.Append(",")
End If
arrayString.Append(param.ToString())
Next
rule.ValidationParameters("targetvalues") = arrayString.ToString()
Return New ModelClientValidationRule() {rule}
End Function
End Class
现在您可以在
Global.asax
的应用程序启动方法中注册所有内容:
DataAnnotationsModelValidatorProvider.RegisterAdapter(GetType(RequiredIfAttribute), GetType(RequiredIfValidator))
这可以让你达到90%的效果。现在你只需要告诉JQuery validate和MS的不唐突验证层如何读取你的新属性:
(function ($) {
$.validator.addMethod('requiredif',
function (value, element, params) {
var dependentVal = $('#' + params['dependentProperty']).val().trim().toLowerCase();
var targetValues = params['targetValues'].split(',');
for (i = 0; i < targetValues.length; i++) {
if (dependentVal == targetValues[i].toLowerCase()) {
return $.trim(value).length > 0;
}
}
return true;
},
'not used');
$.validator.unobtrusive.adapters.add('requiredif', ['dependentProperty', 'targetValues'], function (options) {
options.rules['requiredif'] = options.params;
if (options.message) {
options.messages['requiredif'] = options.message;
}
});
} (jQuery));
希望这能帮到你,这真是一件难事。