自定义客户端验证至少需要一个数组

时间:2014-06-23 14:10:56

标签: jquery asp.net-mvc-4 jquery-validate unobtrusive-validation

我有以下自定义属性,用于验证数组是否已提交值:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class RequiredArrayAttribute : RequiredAttribute, IClientValidatable
{
    public RequiredArrayAttribute()
        : base()
    {
    }

    public override bool IsValid(object value)
    {
        var list = (IList)value;

        if (list != null && list.Count > 0)
        {
            return true;
        }

        return false;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        string errorMessage = this.ErrorMessage;

        // Get the specific error message if set, otherwise the default
        if (string.IsNullOrEmpty(errorMessage) && metadata != null)
        {
            errorMessage = FormatErrorMessage(metadata.GetDisplayName());
        }

        var clientValidationRule = new ModelClientValidationRule()
        {
            ErrorMessage = errorMessage,
            ValidationType = "requiredarray"
        };

        return new[] { clientValidationRule };
    }
}

申请

[RequiredArray(ErrorMessage = "Please select at least one product")]
public IEnumerable<string> ProductIds { get; set; }

以下js(包含在jquery.js之后,unobtrusive-ajax.js,validate.js和validate.unobtrusive.js)

(function ($) {
    $.validator.addMethod('requiredarray', function (value, element, params) {
        var selector = 'input[name=' + $(element).attr('name') + ']:checked';
        return $(selector).length > 0;
    }, 'Clientside Should Not Postback');

    $.validator.unobtrusive.adapters.addBool('requiredarray');
})(jQuery);

我尝试将addMethod更改为return false;,但这仍然无效(我的控制台中没有错误)

我想知道是否有人能发现上述代码我做错了。我已经用地址属性做了类似的事情并且它工作得很好但是由于某种原因我不能让这个工作吗?

此外,服务器端验证也可以。

验证消息的Razor代码

@Html.ValidationMessageFor(m => m.ProductIds)

用于呈现复选框的示例html:

<input type="checkbox" class="checkbox" name="ProductIds" value="EXAMPLEID1234" id="checkbox-1" checked="checked" />
<input type="checkbox" class="checkbox" name="ProductIds" value="EXAMPLEID1235" id="checkbox-2" checked="checked" />

修改

此外,我现在可以使用以下

进行客户端验证
$.validator.addClassRules('required-group', { 'requiredarray': true });

而不是上面的validator.unobtrusive.adapters.addBool方法。我还将课程required-group添加到复选框

但是,如果我使用它,它不会添加正确的MVC错误消息,只需添加上面代码中设置的Clientside Should Not Postback。我已尝试将以下属性添加到复选框:

 data-val="true" data-val-required="Please select at least one sample"

并尝试使用data-val-requiredarray,但这没有区别,所以有人知道如何更改上述客户端规则以使其使用MVC错误消息

1 个答案:

答案 0 :(得分:2)

所以这是通过对html进行以下更改来修复的:

<input type="checkbox" class="checkbox required-group" name="ProductIds" value="EXAMPLEID1234" id="checkbox-1" checked="checked" data-val-required="Please select at least one sample" />
<input type="checkbox" class="checkbox required-group" name="ProductIds" value="EXAMPLEID1235" id="checkbox-2" checked="checked" />

data-val-required只需要在数组中的第一个复选框上。然后使用以下jQuery:

(function ($) {
    $.validator.addMethod('requiredarray', function (value, element, params) {
        return $('input[name=' + $(element).attr('name') + ']:checked').length > 0;
    }, 'Please select at least one');

    $.validator.addClassRules('required-group', { 'requiredarray': true });

    var errorMessage = $('.required-group').eq(0).data('val-requiredarray');
    if (errorMessage && errorMessage !== "") {
        $.validator.messages.requiredarray = errorMessage;
    }
})(jQuery);

我已将addBool更改为addClassRules,然后使用$.validator.messages设置错误消息。