ASP.NET MVC2验证不适用于IE< 8中的下拉列表

时间:2010-06-22 21:52:06

标签: validation asp.net-mvc-2

我有一个表单,其中包含使用Html.DropDownListFor(...)呈现的下拉列表。与下拉列表对应的视图模型字段附加了[Required(...)]属性。这在我的本地计算机上工作正常,但是一旦我发布到我们的开发服务器,下拉列表就会一直显示所需的错误消息,即使在列表中选择了一个值也是如此。这只发生在IE中 - Firefox提交得很好。

有什么想法吗?

相关代码

查看:

<ol class="form">
    <li>
        <%= Html.LabelFor(x => x.ContactTitle) %>
        <%= Html.DropDownListFor(x=>x.ContactTitle, Model.GetTitleOptions()) %>
        <%= Html.ValidationMessageFor(x => x.ContactTitle) %>
    </li>
    <!-- more fields... -->
</ol>

查看型号:

[Required(ErrorMessage = "Title is required")]
[DisplayName("Title")]
public string ContactTitle { get; set; }

// ...

public SelectList GetTitleOptions()
{
    return new SelectList(new string[] 
    {
        "","Dr.", "Mr.", "Ms.", "Mrs.", "Miss"
    });
}

这些都是非常基本的东西......我很茫然。

编辑:刚刚发现此错误仅限于IE 8兼容性视图(可能是以前的版本)。标准模式下的IE 8按预期工作......

1 个答案:

答案 0 :(得分:2)

将这一点归咎于愚蠢。示例中的代码生成类似于以下内容的输出:

<select>
    <option></option>
    <option>Dr.</option>
    <option>Mr.</option>
    <option>Ms.</option>
    <option>Mrs.</option>
    <option>Miss</option>
</select>  

相关的MVC验证函数(当RequiredAttribute应用于与下拉列表对应的属性时)是:

Sys.Mvc.RequiredValidator._validateSelectInput = function Sys_Mvc_RequiredValidator$_validateSelectInput(optionElements) {
    /// <param name="optionElements" type="DOMElementCollection">
    /// </param>
    /// <returns type="Object"></returns>
    for (var i = 0; i < optionElements.length; i++) {
        var element = optionElements[i];
        if (element.selected) {
            if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(element.value)) {
                return true;
            }
        }
    }
    return false;
}

注意功能检查element.value。对于上面的html,value属性为空,因为选项元素上没有value属性。因此,验证函数返回false并发生错误。这似乎只发生在IE&lt; 8中,可能是因为默认情况下其他浏览器会将value元素的文本分配给value属性(如果没有指定)。

解决方案是修改我返回下拉列表的选择列表项的方式,如下所示:

public IEnumerable<SelectListItem> GetTitleOptions()
{
    return BuildSelectListItems(new string[] 
    {
        "","Dr.", "Mr.", "Ms.", "Mrs.", "Miss"
    });
}

private List<SelectListItem> BuildSelectListItems(IEnumerable<string> values) {
    return (from v in values
            select new SelectListItem()
            {
                Text = v,
                Value = v
            }).ToList();
}

这会产生更可预测的HTML输出:

<select>
    <option value=""></option>
    <option value="Dr.">Dr.</option>
    <option value="Mr.">Mr.</option>
    <option value="Ms.">Ms.</option>
    <option value="Mrs.">Mrs.</option>
    <option value="Miss">Miss</option>
</select>

当然功能正确验证。