【问题标题】:How can I check if Model.IsValid when I want to have at least one checkbox value be true?当我想让至少一个复选框值为真时,如何检查 Model.IsValid 是否为真?
【发布时间】:2021-09-01 15:15:46
【问题描述】:

我有一个带有许多复选框的模型。该模型仅在至少选中一个框并选择日期时才有效。模型如下所示:

public class CustomDistricts4Weeks
{
    [DisplayName("002")]
    public bool D2 { get; set; }
    [DisplayName("003")]
    public bool D3 { get; set; }
    [DisplayName("004")]
    public bool D4 { get; set; }
    [DisplayName("005")]
    public bool D5 { get; set; }
    [DisplayName("006")]
    public bool D6 { get; set; }
    [DisplayName("007")]
    public bool D7 { get; set; }
    [DisplayName("ARL")]
    public bool DArl { get; set; }
    [DisplayName("BAR")]
    public bool DBar { get; set; }
    [DisplayName("COL")]
    public bool DCol { get; set; }
    [DisplayName("GER")]
    public bool DGer { get; set; }
    [DisplayName("MEM")]
    public bool DMem { get; set; }
    [DisplayName("LAK")]
    public bool DLak { get; set; }
    [DisplayName("MIL")]
    public bool DMil { get; set; }
    [DisplayName("JAIL")]
    public bool DJail { get; set; }
    [DisplayName("JAILEAST")]
    public bool DJailEast { get; set; }
    [DisplayName("SCCC")]
    public bool DSCCC { get; set; }
    [DisplayName("1USD")]
    public bool D1USD { get; set; }
    [DisplayName("2USD")]
    public bool D2USD { get; set; }
            
    [DataType(DataType.Date, ErrorMessage = "Date Only")]
    [DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}", ApplyFormatInEditMode = true)]
    [Display(Name = "To Date")]
    public DateTime ToDate { get; set; }
}

我确定我可以将 [Required] 放在 ToDate 上,但我如何确保至少有一个布尔值是正确的?任何数字都可以是真的,但至少有一个必须是真的。我可能没有正确解决这个问题,我很想学习更好的方法。我的代码正在运行,但我正在尝试构建验证。

【问题讨论】:

  • 我的错。我说的是model.isvalid,需要modelstate.isvalid。此外,我确实验证了 [Required] 修复了我的 ToDate 要求。现在我需要做的就是确保选中其中一个复选框。

标签: c# asp.net-mvc validation model


【解决方案1】:

定义一个自定义验证属性并将其应用于类。

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

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (validationContext.ObjectInstance is CustomDistricts4Weeks model)
        {
            if (model.D2 || model.D3 || model.D4 ...)
            {
                return ValidationResult.Success;
            }
        }
        return new ValidationResult(ErrorMessage);
    }
}

ModelValidationAttribute 属性应用于数据模型类:

[ModelValidation("Select at least one checkbox")]
public class CustomDistricts4Weeks
{
    [DisplayName("002")]
    public bool D2 { get; set; }

    ...

}

自定义属性的IsValid() 方法可能会更改为使用反射来枚举模型中的所有属性。在这种情况下,不需要使用所有属性名称。当然只有在所有bool属性都应该被测试的情况下:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var model = (Movie)validationContext.ObjectInstance;
    PropertyInfo[] myPropertyInfo  = model.GetType().GetProperties();
    for (int i = 0; i < myPropertyInfo.Length; i++)
    {
        var prop = myPropertyInfo[i];               
        if (prop.PropertyType.Equals(typeof(bool)) 
            && prop.GetCustomAttributes(typeof(DisplayNameAttribute), false).Length > 0
            && prop.GetValue(model) is bool pval && pval)
        {
            return ValidationResult.Success;                    
        }
    }
    return new ValidationResult(ErrorMessage);
}

【讨论】:

  • 这看起来像我要找的。我明天会测试,看看它是如何工作的。谢谢!
  • 这非常有效。非常感谢。
  • @Steve Cross:不客气!如果有兴趣,我添加了一个小改动。
  • 谢谢你。我会调查这口井。
猜你喜欢
  • 2021-11-14
  • 2021-09-29
  • 2017-10-06
  • 2015-09-22
  • 2023-03-19
  • 2016-05-19
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多