如果未选择任何项目,ListBoxFor 不显示 ValidationMessageFor

ListBoxFor not showing ValidationMessageFor if no items are selected

我有一个如下所示的列表框:

 @Html.Label("Members", htmlAttributes: new { @class = "control-label required", @multiple = "multiple" })
 @Html.ListBoxFor(model => model.Members, (IEnumerable<SelectListItem>)ViewBag.Members, new { @class = "form-control", @multiple = "multiple" })                                               
 @Html.ValidationMessageFor(model => model.Members, "", new { @class = "text-danger" })

我遇到的问题是,即使没有选择成员,它也不会显示验证消息。

    [Required(ErrorMessage = "Please select a member")]
    public List<int> Members { get; set; }

如果您在 reference source 中选中 RequiredAttribute,您将看到重写的 IsValid 方法,如下所示:

public override bool IsValid(object value) 
{
    // checks if the object has null value
    if (value == null) 
    {
        return false;
    }

    // other stuff

    return true;
}

这里的问题是 IsValid 方法只检查空值和空对象,但不检查集合对象中存在的 Count 属性,例如IEnumerable<T>。如果要检查零值 Count 属性(表示未选择项目),则需要创建继承自 RequiredAttribute 的自定义注释属性,其中包含 IEnumerator.MoveNext() 检查并应用它到 List<T> 属性:

[AttributeUsage(AttributeTargets.Property)]
public sealed class RequiredListAttribute : RequiredAttribute
{
    public override bool IsValid(object value)
    {
        var list = value as IEnumerable;

        // check against both null and available items inside the list
        return list != null && list.GetEnumerator().MoveNext();
    }
}

// Viewmodel implementation
public class ViewModel
{
    [RequiredList(ErrorMessage = "Please select a member")]
    public List<int> Members { get; set; }
}

注:

使用 int[] 数组类型而不是 List<int> 例如public int[] Members { get; set; } 应该适用于标准 RequiredAttribute 因为数组 属性 returns null 当没有选择项目时,而 List<T> 属性调用默认构造函数,它将创建一个空列表。

相关问题:

Required Attribute on Generic List Property