C# 使用IValidatableObject时,所需属性未出现在错误列表中

C# 使用IValidatableObject时,所需属性未出现在错误列表中,c#,asp.net-mvc,validation,C#,Asp.net Mvc,Validation,我有一个类在某些属性上有[必需的]装饰,但也需要一些自定义验证,因此它使用IValidatableObject 等级 公共类模型课程:IValidatableObject { //其他一些代码。。。 [显示名称(“课程名称”)] [必需] [StringLength(100,最小长度=1)] 公共字符串名称{get;set;} //更多代码。。。 公共IEnumerable验证(ValidationContext ValidationContext) { if(courseGradeLevels

我有一个类在某些属性上有
[必需的]
装饰,但也需要一些自定义验证,因此它使用
IValidatableObject

等级
公共类模型课程:IValidatableObject
{
//其他一些代码。。。
[显示名称(“课程名称”)]
[必需]
[StringLength(100,最小长度=1)]
公共字符串名称{get;set;}
//更多代码。。。
公共IEnumerable验证(ValidationContext ValidationContext)
{
if(courseGradeLevels==null | | courseGradeLevels.Count<1)
{
返回新的ValidationResult(“您必须至少选择一个级别”);
}
if((courseLength==courseLength.Other)&&string.IsNullOrEmpty(courseLength描述))
{
返回新的ValidationResult(“如果长度为其他长度,则需要课程长度描述”);
}
}
}
验证
//课程是此类中少数几个子对象之一
bool dbDetailsValid=TryValidateModel(dbDetails);
ViewData[“courseValid”]=!ModelState.ContainsKey(“课程”);
foreach(ModelState.Where(x=>x.Value.Errors.Count>0)中的KeyValuePair对)
{
ViewData[pair.Key+“ErrorList”]=pair.Value.Errors.ToList();
}

运行此代码时,
name
的空白字符串不会导致
ModelState
中出现错误。自定义验证逻辑按预期工作,但我不明白为什么
TryValidateModel
没有注意到装饰。。。手动检查每个必填字段是我唯一的选择吗?

多亏@nick nieslanik给我指了指,我有了答案

在我的自定义验证方法中,我使用反射循环遍历每个属性,并对每个属性调用
TryValidateProperty
,如果没有验证,则将其添加到结果中:

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        foreach (PropertyInfo property in this.GetType().GetProperties())
        {
            Validator.TryValidateProperty(property.GetValue(this), new ValidationContext(this, null, null) { MemberName = property.Name }, results);
            if (results.Count > 0)
            {
                foreach (ValidationResult err in results)
                {
                    yield return new ValidationResult(err.ErrorMessage);
                }
                results.Clear();
            }
        }
        //the rest of the validation happens here...
    }
公共IEnumerable验证(ValidationContext ValidationContext) { 列表结果=新列表(); foreach(此.GetType().GetProperties()中的PropertyInfo属性) { TryValidateProperty(property.GetValue(this),新的ValidationContext(this,null,null){MemberName=property.Name},results); 如果(results.Count>0) { foreach(结果中的ValidationResult错误) { 返回新的ValidationResult(err.ErrorMessage); } 结果:清晰(); } } //剩下的验证在这里进行。。。 }
您当前的代码-StringLength的最大值应为100。您还需要指定在本例中为1的最小值。(命名参数:MinimumLength)好主意,但我刚刚尝试添加属性,modelstate中仍然没有错误。这里仍然需要添加MinimumLength。在任何情况下,执行TryValidateModel时,dbDetailsValid的值是多少?它为false,但在另一个子对象上失败
ModelState.ContainsKey(“课程”)
返回false。课程中没有错误。如果我违反了我的
Validate
方法中的某个策略,它将按预期显示。详细信息:尝试注释掉所有自定义验证,只保留
[必需]
[StringLength…]
属性。在父级上调用validate时仍然没有错误,子级中有一个已确认的空字符串。
        //course is one of a few child objects in this class
        bool dbDetailsValid = TryValidateModel(dbDetails);

        ViewData["courseValid"] = !ModelState.ContainsKey("course");

        foreach(KeyValuePair<string, ModelState> pair in ModelState.Where(x => x.Value.Errors.Count > 0))
        {
            ViewData[pair.Key + "ErrorList"] = pair.Value.Errors.ToList();
        }
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        List<ValidationResult> results = new List<ValidationResult>();
        foreach (PropertyInfo property in this.GetType().GetProperties())
        {
            Validator.TryValidateProperty(property.GetValue(this), new ValidationContext(this, null, null) { MemberName = property.Name }, results);
            if (results.Count > 0)
            {
                foreach (ValidationResult err in results)
                {
                    yield return new ValidationResult(err.ErrorMessage);
                }
                results.Clear();
            }
        }
        //the rest of the validation happens here...
    }