【问题标题】:MVC Custom Validation for List on Client Side客户端列表的 MVC 自定义验证
【发布时间】:2015-03-13 15:34:40
【问题描述】:

我正在尝试编写一个在客户端工作的自定义验证器,用于验证所有复选框是否已被勾选。

这是模型的声明:

[DeclarationsAccepted(ErrorMessage = "You must tick all declarations")]        
    public IList<DeclarationQuestion> DeclarationQuestions { get; set; }

这是属性:

public class DeclarationsAccepted : ValidationAttribute, IClientValidatable
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {

        var questions = value as IList<DeclarationQuestion>;

        if (questions != null && questions.All(c => c.Answer))
        {
            return ValidationResult.Success;
        }
        return new ValidationResult("You must accepted all declarations to continue");
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var modelClientValidationRule = new ModelClientValidationRule
        {
            ValidationType = "declarationsaccepted",
            ErrorMessage = FormatErrorMessage(metadata.DisplayName)
        };            
        yield return modelClientValidationRule;
    }
}

到目前为止一切顺利,可以在服务器端工作。

对于客户端,我将其连接如下:

jQuery.validator.addMethod('declarationsaccepted', function (value, element, params) {

        //Implement logic here to check all boxes are ticked
        console.log(value);

        return false;
    }, '');


    jQuery.validator.unobtrusive.adapters.add('declarationsaccepted', {}, function (options) {
        options.rules['declarationsaccepted'] = true;
        options.messages['declarationsaccepted'] = options.message;
    });

我正在显示这样的复选框:

@{ var questionIndex = 0; }
        @foreach (var question in Model.DeclarationQuestions)
        {

                @Html.CheckBoxFor(model => Model.DeclarationQuestions[questionIndex].Answer, new { id = "DeclarationQuestions" + questionIndex})

            questionIndex++;
        }

然后使用这个显示验证消息:

@Html.ValidationMessageFor(c => c.DeclarationQuestions)

当我提交表单时,会显示消息,但仅在发回服务器后才会显示。有没有办法让它在客户端工作?

【问题讨论】:

  • 客户端是否有任何验证工作?如果不是,您需要包含 jquery.validate.js 和 jquery.validate.unobtrusive.js。
  • 是的验证正在客户端工作,我可以将该属性应用于其他属性,例如文本输入。

标签: asp.net-mvc asp.net-mvc-4


【解决方案1】:

您无法获得客户端验证的原因是 html 帮助程序为与属性关联的控件生成 data-val-* 属性。 jquery.validate.unobtrusive 在解析表单并使用规则时读取这些属性,在与该控件关联的ValidationMessageFor() 生成的适当元素中显示错误消息(它通过匹配元素的id 属性来实现 - 错误消息在带有&lt;span for="TheIdOfTheAssociatedControl" ...&gt; 的范围内生成。

您不(也不能)为属性DeclarationQuestions 生成控件(仅针对DeclarationQuestions 中每个项目的属性,因此没有可以匹配的内容。

您可以通过包含自己的错误消息占位符并拦截.submit 事件来处理此问题

html(将 CSS 添加到样式 #conditions-errordisplay:none;

<span id="delarations-error" class="field-validation-error">
  <span>You must accept all declarations to continue.</span>
</span>

脚本

var declarationsError = $('#delarations-error');
$('form').submit(function() {
  var isValid = $('.yourCheckBoxClass').not(':checked') == 0;
  if(!isValid) {
    declarationsError.show(); // display error message
    return false; // prevent submit
  }
});

$('.yourCheckBoxClass').change(function() {
  if($(this).is(':checked')) {
    declarationsError.hide(); // hide error message
  }
});

旁注:生成复选框的循环应该是

for (int i = 0; i < Model.DeclarationQuestions.Count; i++)
{
  @Html.CheckBoxFor(m => m.DeclarationQuestions[i].Answer, new { id = "DeclarationQuestions" + i})
}

【讨论】:

  • 谢谢。我将使用您上面建议的解决方案来实施
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
相关资源
最近更新 更多