asp.net mvc客户端验证

asp.net mvc客户端验证,asp.net,asp.net-mvc,Asp.net,Asp.net Mvc,在阅读了这个主题之后,我一直在修补ASP.net MVC中的客户端验证功能。使用System.Componentmodel.DataAnnotations属性非常简单,如下所示: [Required(ErrorMessage = "You must specify a reason")] public string ReasonText { get; set; } 。。。但是如果你需要更复杂一点的东西会发生什么呢。如果您有一个带有PostalCode和CountryCode字段

在阅读了这个主题之后,我一直在修补ASP.net MVC中的客户端验证功能。使用System.Componentmodel.DataAnnotations属性非常简单,如下所示:

    [Required(ErrorMessage = "You must specify a reason")]
    public string ReasonText { get; set; }
。。。但是如果你需要更复杂一点的东西会发生什么呢。如果您有一个带有PostalCode和CountryCode字段的Address类,该怎么办。您可能希望根据每个国家/地区的不同正则表达式验证邮政编码。[0-9]{5}适用于美国,但您需要一个适用于加拿大的不同版本

我通过滚动我自己的ValidationService类来解决这个问题,该类接受控制器的ModelState属性并相应地对其进行验证。这在服务器端非常有效,但不适用于新奇的客户端验证

在Webforms中,我会使用javascript发出控件,如RequiredFieldValidator或CompareValidator来处理简单的内容,然后使用CustomValidator来处理复杂的规则。通过这种方式,我将所有的验证逻辑放在一个地方,我获得了简单东西的快速javascript验证(90%的时间)的好处,同时我还获得了服务器端验证的安全性作为后盾


MVC中的等效方法是什么

我刚刚在MVC 3中看到了一些关于IValidatableObject接口的内容,我将尝试一下。

从中派生您自己的验证属性并相应地应用逻辑。在MVC2中,为了基于另一个属性的值执行属性的验证,必须在您注册以使用自定义验证属性的验证器内完成(假设您使用)

因为在验证属性中,您只能访问属性绑定到的属性值,而不能访问模型


查看以了解此方法是如何实现的。

编辑:这假设您使用的是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
现在,您可以在
Global.asax的应用程序启动方法中注册所有内容:

DataAnnotationsModelValidatorProvider.RegisterAdapter(GetType(RequiredIfAttribute), GetType(RequiredIfValidator))
这可以让你达到90%的目标。现在,您只需要告诉JQuery validate和MS的低调验证层如何读取新属性:

/// <reference path="jquery-1.4.1-vsdoc.js" />
/// <reference path="jquery.validate-vsdoc.js" />

/* javascript for custom unobtrusive validation
   ==================================================== */

(function ($) {

    // this adds the custom "requiredif" validator to the jQuery validate plugin
    $.validator.addMethod('requiredif',
                          function (value, element, params) {

                              // the "value" variable must not be empty if the dependent value matches
                              // one of the target values
                              var dependentVal = $('#' + params['dependentProperty']).val().trim().toLowerCase();
                              var targetValues = params['targetValues'].split(',');

                              // loop through all target values
                              for (i = 0; i < targetValues.length; i++) {
                                  if (dependentVal == targetValues[i].toLowerCase()) {
                                      return $.trim(value).length > 0;
                                  }
                              }

                              return true;
                          },
                          'not used');

    // this tells the MS unobtrusive validation layer how to read the
    // HTML 5 attributes that are output for the custom "requiredif" validator
    $.validator.unobtrusive.adapters.add('requiredif', ['dependentProperty', 'targetValues'], function (options) {

        options.rules['requiredif'] = options.params;
        if (options.message) {
            options.messages['requiredif'] = options.message;
        }

    });

} (jQuery));
//
/// 
/*用于自定义不引人注目的验证的javascript
==================================================== */
(函数($){
//这会将自定义“requiredif”验证器添加到jQuery验证插件中
$.validator.addMethod('requiredif',
函数(值、元素、参数){
//如果依赖值匹配,“value”变量不得为空
//目标值之一
var dependentVal=$('#'+params['dependentProperty']).val().trim().toLowerCase();
var targetValues=params['targetValues'].split(',');
//循环遍历所有目标值
对于(i=0;i0;
}
}
返回true;
},
“未使用”);
//这将告诉MS unobtrusive验证层如何读取
//为自定义“requiredif”验证器输出的HTML 5属性
$.validator.unobtrusive.adapters.add('requiredif',['dependentProperty','targetValues',函数(选项){
options.rules['requiredif']=options.params;
if(options.message){
options.messages['requiredif']=options.message;
}
});
}(jQuery));

希望这能有所帮助,工作起来真的很痛苦。

ScottGu今天早上在推特上说Pluralsight在接下来的48小时内是如何免费的。他们有一个视频展示了如何进行这种定制验证。相关视频位于“ASP.NET MVC 3.0中的模型”下,特别是“自定义验证属性”和“自验证模型”。我认为解决您问题的方法是MVC中的
System.ComponentModel.DataAnnotations

对于复杂逻辑,您可以实现自己的逻辑。这很容易。 查看此链接上的自定义设置:

对于最基本的事情,请使用模型类查看绑定,并在属性顶部添加属性。。。 像


使用该类查看强类型

我对此不确定,但我认为您必须为类似的自定义内容推出自己的客户端验证。也许可以看看Jquery验证,您的目标是哪个版本的ASP.NET MVC?这是否会在开箱即用的客户端验证中自动获得?@CRice-如果从System.ComponentModel.DataAnnotations中的一个属性派生,那么客户端将为您处理。如果定义自己的验证AtterBute,还需要自己编写客户端逻辑。假设您使用jQuery验证,您将添加一个validator函数来调用jQuery validation,该函数由一个字符串键入,在验证规则与键匹配时使用。系统如何知道要输出什么javascript来验证从system.ComponentModel.DataAnnotations.ValidationAttribute继承的任何自定义类?请看一个示例。@CRice-您的验证器根据验证属性注册的方法名为
GetClientValidationRules
。在这个方法中,您为
ValidationType分配一个字符串值<
DataAnnotationsModelValidatorProvider.RegisterAdapter(GetType(RequiredIfAttribute), GetType(RequiredIfValidator))
/// <reference path="jquery-1.4.1-vsdoc.js" />
/// <reference path="jquery.validate-vsdoc.js" />

/* javascript for custom unobtrusive validation
   ==================================================== */

(function ($) {

    // this adds the custom "requiredif" validator to the jQuery validate plugin
    $.validator.addMethod('requiredif',
                          function (value, element, params) {

                              // the "value" variable must not be empty if the dependent value matches
                              // one of the target values
                              var dependentVal = $('#' + params['dependentProperty']).val().trim().toLowerCase();
                              var targetValues = params['targetValues'].split(',');

                              // loop through all target values
                              for (i = 0; i < targetValues.length; i++) {
                                  if (dependentVal == targetValues[i].toLowerCase()) {
                                      return $.trim(value).length > 0;
                                  }
                              }

                              return true;
                          },
                          'not used');

    // this tells the MS unobtrusive validation layer how to read the
    // HTML 5 attributes that are output for the custom "requiredif" validator
    $.validator.unobtrusive.adapters.add('requiredif', ['dependentProperty', 'targetValues'], function (options) {

        options.rules['requiredif'] = options.params;
        if (options.message) {
            options.messages['requiredif'] = options.message;
        }

    });

} (jQuery));
public class CustomerSearchDE
{
    [StringLength(2, ErrorMessageResourceType = typeof(Translation), ErrorMessageResourceName = MessageConstants.conCompanyNumberMaxLength)]
    public string CompanyNumber { get; set; }
 }