我是新的ASP.NETMVC和工作的形式验证.我被一组复选框验证卡住了.基本上,我试图让用户在一组复选框中 Select 至少一个爱好.

下面的模型.您可以看到,我试图实现AtLeastOneCheckedAttribute,但无法使其正常工作.

public class EmployeeModel2
{
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please Provide First Name")]
    [StringLength(20, MinimumLength = 5, ErrorMessage = "First Name Should be min 5 and max 20 length")]
    public string FirstName { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Please Provide Last Name")]
    [StringLength(20, MinimumLength = 5, ErrorMessage = "First Name Should be min 5 and max 20 length")]
    public string LastName { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Please Provide Eamil")]
    [RegularExpression("^[a-zA-Z0-9_\\.-]+@([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$", ErrorMessage = "Please Provide Valid Email")]
    public string Email { get; set; }

    [Required(AllowEmptyStrings = false, ErrorMessage = "Please Provide Age")]
    [Range(25, 45, ErrorMessage = "Age Should be min 25 and max 45")]
    public int? Age { get; set; }

    [Required(ErrorMessage = "Please Provide Gender")]
    public string Gender { get; set; }

    //[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    [Required(ErrorMessage = "Please enter Date of Birth")]
    public DateTime DOB { get; set; }

    [DataType(DataType.Password)]
    [Required(ErrorMessage = "Please enter password")]
    public string Password { get; set; }

    [Required(ErrorMessage = "Please enter ConfirmPassword")]
    [DataType(DataType.Password)]
    [Compare("Password", ErrorMessage = "Password not matching")]
    public string ConfirmPassword { get; set; }
    
    public List<HobbyMV> Hobbies { get; set; }

    [AtLeastOneChecked(ErrorMessage = "Please select at least one checkbox")]
    public int[] selectedHobbies { get; set; }
}

// I tried this code, but it is not working properly
public class AtLeastOneCheckedAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        var instance = value as IEnumerable<HobbyMV>;

        if (instance != null)
        {
            return true;
        }

        return false;
    }
}

视图中的表格.问题是,即使我选中了几个复选框,selectedHobbies个组复选框仍会提示"请至少 Select 一个复选框".

@using (Html.BeginForm("Validation2", "XForm", FormMethod.Post, htmlAttributes: new
{@class = "form"}))
{
    @Html.AntiForgeryToken()

    <div class="form-group">
        @Html.LabelFor(model => model.FirstName)
        @Html.TextBoxFor(model => model.FirstName, new { @class = "form-control", title = "Enter your first name" })
        @Html.ValidationMessageFor(m => m.FirstName, "", new {@class = "text-danger"})
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.LastName)
        @Html.TextBoxFor(model => model.LastName, new { @class = "form-control", title = "Enter your last name" })
        @Html.ValidationMessageFor(m => m.LastName, "", new {@class = "text-danger"})
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Email)
        @Html.TextBoxFor(model => model.Email, new { @class = "form-control", title = "Enter your email address" })
        @Html.ValidationMessageFor(m => m.Email, "", new {@class = "text-danger"})
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Age)
        @Html.TextBoxFor(model => model.Age, new { @class = "form-control", title = "Enter your age" })
        @Html.ValidationMessageFor(m => m.Age, "", new {@class = "text-danger"})
    </div>
 
    <div class="editor-field">
        @Html.EditorFor(model => model.DOB)
        @Html.ValidationMessageFor(model => model.DOB, "", new {@class = "text-danger"})
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.Password)
    </div>

    <div class="editor-field">
        @Html.EditorFor(model => model.Password)
        @Html.ValidationMessageFor(model => model.Password, "", new {@class = "text-danger"})
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.ConfirmPassword, "", new {@class = "text-danger"})
    </div>

    <div class="editor-field">
        @Html.EditorFor(model => model.ConfirmPassword)
        @Html.ValidationMessageFor(model => model.ConfirmPassword, "", new {@class = "text-danger"})
    </div>

    <div class="form-group" >
        <label><b>Gender</b></label>
        <div> 
            @Html.RadioButtonFor(m => m.Gender, "Male") 
            <label>Male</label>
            @Html.RadioButtonFor(m => m.Gender, "Female") 
            <label> Female </label>
            @Html.ValidationMessageFor(m => m.Gender, "", new {@class = "text-danger"}) 
        </div>
    </div>

    <div class="form-group" >
        <label><b>Hobby</b></label><br/>
        @foreach (var item in Model.Hobbies)
        {
            <span style="padding:10px;">
                <label><input type="checkbox" value="@item.HobbyId" checked="@item.IsSelected" name="selectedHobbies" id="@item.HobbyId" /> @Html.Raw(@item.Description)</label>
            </span>
        }
        @Html.ValidationMessageFor(m => m.selectedHobbies, "", new {@class = "text-danger"})
    </div>

    <div class="form-group"> 
         <input type = "submit" value="Submit" class="btn-success" /> 
     </div>
}

如果我为这个爱好 Select 了一些复选框,然后点击提交,它没有通过验证(下面的截图),并且消息"请至少 Select 一个复选框"不会消失.

enter image description here

请帮帮忙.先谢谢你.

推荐答案

try 使用索引来为Hobbies进行列表绑定,以正确工作:

<div class="form-group" >
    <label><b>Hobby</b></label><br/>   
    @for (int i = 0; i < Model.Hobbies.Count; i++)
    {
        <span style="padding:10px;">      
            @Html.CheckBoxFor(r => Model.Hobbies[i].IsSelected)
            @Html.Raw(@Model.Hobbies[i].Description)
            @Html.HiddenFor(h => @Model.Hobbies[i].HobbyId)
            @Html.HiddenFor(h => @Model.Hobbies[i].Description)
        </span>          
    }
    @Html.ValidationMessageFor(m => m.Hobbies, "", new { @class = "text-danger" })
</div>

将自定义属性指定为AttributeTargets.Property:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class AtLeastOneCheckedAttribute : ValidationAttribute
{
    public AtLeastOneCheckedAttribute(string errorMessage) : base(errorMessage)
    {
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)    
    {
        // Check that list doesn't empty and at least one item is selected
        if (value is IEnumerable<HobbyMV> list && list.Any(h => h.IsSelected))
        {
            return ValidationResult.Success;
        }
        return new ValidationResult(ErrorMessage); 
    }
}

并将AtLeastOneChecked属性应用于Hobbies列表:

[AtLeastOneChecked("Please select at least one checkbox")]
public List<HobbyMV> Hobbies { get; set; }

Csharp相关问答推荐

FromServices不使用WebAppliationFactory程序>

EF Core在请求列表时忽略列,但在按ID获取时包含

始终保留数组中的最后N个值,丢弃最老的

`Task`只有在C#中等待时才会运行吗?

如何让NLog停止写入冗余信息?

从VS调试器而不是测试资源管理器运行的调试NUnitDotNet测试

N层解决方案上的依赖注入-删除样板

如何使用.NET6WPF打印车票?

为什么@rendermode Interactive Auto不能在.NET 8.0 Blazor中运行?

源代码生成器:CS8795分部方法';Class1.GetS2(字符串)';必须有实现部分,因为它有可访问性修饰符?

Postgres ENUM类型在第一次运行时对Dapper不可见

Content WithTargetPath实际上是有效的MSBuild项吗?

为什么ReadOnlySpan;T&>没有Slice(...)的重载接受Range实例的?

我可以强制System.Text.Json.JsonSerializer以非递归方式工作吗?

在.NET Maui中,Flyoutindow/Hamburger菜单可以在shell 之外实现吗?

如何使用IHostedService添加数据种子方法

WPF:如何从DatagridHeader的内容模板绑定到词典项

ASP.NET Core 8 Web API:如何添加版本控制?

使用LibraryImport在多个dll中导入相同的函数

使用';UnityEngineering.Random.Range()';的IF语句仅适用于极高的最大值