【问题标题】:ASP.NET MVC Custom validation for a List<string>List<string> 的 ASP.NET MVC 自定义验证
【发布时间】:2016-03-07 17:17:37
【问题描述】:

我正在使用 ASP.NET MVC 5,并且在客户端想要使用 JQuery 不显眼的验证。

以下是我的模型:

 public class CompanyModel
    {
        public CompanyModel()
        {
            Employees = new List<EmployeeModel>();              
        }
        public int CompanyId{ get; set; }

        public List<EmployeeModel> Employees { get; set; }        
    }

    public class EmployeeModel
    {
        public EmployeeModel()
        {
            Values = new List<string>();
        }

        public string Id { get; set; }

        public string Name { get; set; }

        [RequiredIf("IsRequired", true, "Atleast one value is required")]
        public List<string> Values { get; set; }

        public bool IsRequired { get; set; }
    }

我能够在服务器端成功实现RequiredIf 自定义属性。但是我正在努力进行客户端验证...

在视图中,我遍历员工列表并绑定了值集合

@for (var index = 0; index < Model.Employees.Count; index++)
{
      /// some other code

    @for (int i = 0; i < Model.employees[index].Values.Count; i++)
    {
        @Html.TextBoxFor(m => m.Employees[index].Values[i], new {@autocomplete = "false" })
    }    
 }

IsRequired 属性是一个隐藏字段:

@Html.HiddenFor(m => m.Employees[index].IsRequired)

以下是我目前为 GetClientValidationRules 方法编写的代码。

  public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
            {
                var rule = new ModelClientValidationRule
                {
                    ErrorMessage = ErrorMessage,
                    ValidationType = "requiredif"
                };               

                rule.ValidationParameters["dependentproperty"] = (context as ViewContext).ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty);
                rule.ValidationParameters["dependentpropertyvalue"] = DependentPropertyValue.ToString().ToLower();

                yield return rule;            
            }

我没有看到将验证 html (data-val-*) 属性添加到 HTML 标记中的值。而且我也不指望他们,因为我认为我错过了一些东西。如何在 html 中获取使用 data-val-requiredif 属性填充的 values 集合的所有元素。

有什么想法吗?

仅供参考:html 中的dependentpropertyId 填充为 CompanyModel.Employees_0_IsRequired for Employee[0]。

【问题讨论】:

  • 您无法为集合的属性获取 jquery 客户端验证,因为您无法为集合生成表单控件(仅适用于集合的属性)。您需要编写自己的客户端脚本才能显示您自己的客户端消息。
  • 好的,谢谢,我明白了。 @StephenMuecke 然后你建议做一些类似于接受的答案在这里建议的事情。 stackoverflow.com/questions/5662589/… 还是手动给html添加data-val和data-val-requiredif属性然后写一个jquery验证适配器?
  • @Sparky(stackoverflow.com/users/594235/sparky) 你也有同样的问题吗?
  • 我对 ASP 或其 Unobtrusive 插件了解不多,但就 jQuery Validate 而言,不需要特殊方法来验证一组复选框或单选按钮。见:jsfiddle.net/af68u6z3
  • 我也看不到你渲染的 HTML,所以我不知道 List&lt;string&gt; 应该是什么。但是,使用 jQuery Validate 只能验证 textareaselect 和各种类型的 input 元素;没有别的。

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


【解决方案1】:

在您的验证属性中包含GetClientValidationRules() 方法没有什么意义,因为它的目的是将data-val-* 属性添加到为该属性生成的表单控件中,并且您不会为属性@987654323 生成输入@ (如果你这样做了,绑定会失败)。解决此问题的一种方法是处理表单.submit() 事件,检查集合中是否至少有一项具有值,如果没有则取消提交并显示错误。

修改您的视图以包含验证消息占位符并将类名添加到输入以供选择

@for (var index = 0; index < Model.Employees.Count; index++)
{
    ....
    <div class="value-group"> // necessary for relative selectors
        @for (int i = 0; i < Model.employees[index].Values.Count; i++)
        {
            @Html.TextBoxFor(m => m.Employees[index].Values[i], new { @class="value", autocomplete = "false" })
        }
        @Html.ValidationMessageFor(m => m.Employees[index].Values)
   </div>
}

并包含以下脚本

$('form').submit(function() { // use an id selector if you have added one to the form
    var isValid = true;
    var groups = $('.value-group');
    $.each(groups, function(index, item) {
        var group = $(this);
        var inputs = group.find('.value');
        if (inputs.filter(function () { return $(this).val().length > 0; }).length == 0) {
            isValid = false;
            group.find('span:last').append($('<span></span>').text('At least one value is required')).addClass('field-validation-error').removeClass('field-validation-valid');
        }
    });
    return isValid;
});

如果组中的任何输入现在具有值,您可能还需要添加另一个脚本来处理每个输入的更改事件以删除相关的错误消息

【讨论】:

    【解决方案2】:

    Required 验证仅确保属性具有值。在List&lt;string&gt; 之类的情况下,这仅意味着它不为空。一个空列表仍然是一个列表,因此它可以很好地通过验证。实际上,您使用的是RequiredIf,并且没有提供该自定义属性的实现,但我认为它依赖于基本Required 属性,因为我见过的几乎所有实现都可以。

    总之,您要么需要修改 RequiredIf 实现以考虑列表的内容和其他可枚举属性,要么您需要添加一些手动验证以检查列表实际上是否至少有一个项目。

    【讨论】:

    • 是的,我检查了列表中的计数以确保计数 > 0,这是服务器端。我无法让客户端工作。
    猜你喜欢
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 2017-06-21
    • 1970-01-01
    相关资源
    最近更新 更多