5

我的stringlength验证在带有字符串值的下拉列表上总是失败。MVC DropDownListFor和StringLength属性不能很好地一起播放

这里是我的模型:

[Required(ErrorMessage = "Required")] 
[StringLength(2, MinimumLength = 2)] 
[Display(Name = "Home Address State")] 
public string HomeAddressState { get; set; } 

这是我的观点:

@Html.DropDownListFor(model => model.HomeAddressState, new SelectList(ViewBag.States, "Value", "Text"), string.Empty) 
@Html.ValidationMessageFor(model => model.HomeAddressState) 

下面是HTML输出:

<select data-val="true" data-val-length="The field Home Address State must be a string with a minimum length of 2 and a maximum length of 2." data-val-length-max="2" data-val-length-min="2" data-val-required="Required" id="HomeAddressState" name="HomeAddressState"><option value=""></option> 
<option value="CA">California</option> 
<option value="IL">Illinois</option> 
<option value="IN">Indiana</option> 
<option value="OH">Ohio</option> 
</select> 

无论选择哪一选项,则StringLength客户端验证失败。我做错了什么?

+1

为什么你需要StringLength验证下拉列表? – Jesse 2012-07-10 16:23:23

+1

可能是因为他的数据模型验证是(正确)独立于他的客户端视图。 – bhamlin 2012-07-10 16:33:02

+0

bhamlin是正确的。我使用[StringLength(2,MinimumLength = 2)]在我的数据库中正确地创建char(2)字段,因为我使用的是代码优先。我不想流利的方式。 – 2012-07-10 18:17:41

回答

0

因为StringLength匹配rangelength规则在jquery.validate。在选择列表的情况下,它将检查所选项目的数量而不是所选值的长度,因此如果您编写最小长度为1的规则,它将起作用

6

以下是相关的jquery验证代码。正如您所看到的,它看起来像是将长度验证应用于所选选项的数量,而不是选项的长度。似乎只适用于多选列表框。有点奇怪,说实话。

maxlength: function(value, element, param) { 
    return this.optional(element) || this.getLength($.trim(value), element) <= param; 
} 

getLength: function(value, element) { 
    switch(element.nodeName.toLowerCase()) { 
     case 'select': 
      return $("option:selected", element).length; 
     case 'input': 
      if(this.checkable(element)) 
       return this.findByName(element.name).filter(':checked').length; 
    } 
    return value.length; 
} 

你可以做的是重写getLength功能自己只是直接返回value.length

$.validator.prototype.getLength = function (value, element) { 
    return value.length; 
} 
+1

谢谢。我会把这个代码放在哪里? – 2012-07-10 18:28:54

+0

包含jquery验证库后的任何地方。 – bhamlin 2012-07-10 23:42:33

+0

这就是我的想法,但没有骰子。默认行为胜过我的重写。我想知道验证库是如何实际实例化的。它看起来像是一个懒惰的负载。在$(document).ready()中,我查询了$ .validator.methods.getLength,它是空的。 – 2012-07-11 13:52:14

2

为了避免打破了复选框和多个selectboxes逻辑,你可以使用:

$.validator.prototype.getLength = function (value, element) { 
    switch (element.nodeName.toLowerCase()) { 
     case 'select': 
      { 
       var attr = $(this).attr('multiple'); 
       // For some browsers, `attr` is undefined; for others, 
       // `attr` is false. Check for both. 
       if (typeof attr !== 'undefined' && attr !== false) { 
        return $("option:selected", element).length; 
       } 
      } 
     case 'input': 
      if (this.checkable(element)) 
       return this.findByName(element.name).filter(':checked').length; 
    } 
    return value.length; 
} 

警告:我测试这个只在DropDownFor,所以在使用您自担风险....