自定义 RequiredIfAttribute 在 ModelState.IsValid 检查时未生成错误消息

Custom RequiredIfAttribute not producing error message on ModelState.IsValid check

我有一个自定义的必需 if 属性,我使用该属性根据是否在另一个下拉列表中选择了值来验证下拉列表。

下面的代码是自定义属性当前使用的代码:

public class RequiredIfAttribute : ValidationAttribute
    {
        private const string DefaultErrorMessageFormatString = "The {0} field is required.";
        private readonly string[] _dependentProperties;
        
        public RequiredIfAttribute(string[] dependentProperties)
        {
            _dependentProperties = dependentProperties;
            ErrorMessage = DefaultErrorMessageFormatString;
        }
        
        private bool IsValueRequired(string checkValue, Object currentValue)
        {
            if (checkValue.Equals("!null", StringComparison.InvariantCultureIgnoreCase))
            {
                return currentValue != null;
            }

            return checkValue.Equals(currentValue);
        }
        
        protected override ValidationResult IsValid(Object value, ValidationContext context)
        {
            Object instance = context.ObjectInstance;
            Type type = instance.GetType();
            bool valueRequired = false;

            foreach (string s in _dependentProperties)
            {
                var fieldValue = s.Split(',').ToList().Select(k => k.Trim()).ToArray();

                Object propertyValue = type.GetProperty(fieldValue[0]).GetValue(instance, null);

                valueRequired = IsValueRequired(fieldValue[1], propertyValue);
            }

            if (valueRequired)
            {
                return value != null
                    ? ValidationResult.Success
                    : new ValidationResult(context.DisplayName + " required. ");
            }
            return ValidationResult.Success;
        }
    }

我当前在模型中定义的属性是这样的:

[RequiredIf(new[] {"OrganisationType,1", "OrganisationType, 9", "OrganisationType, 10"})]

第一个值是从属下拉列表,第二个是来自所述下拉列表的 ID,必须为另一个下拉列表的值选择该 ID。

下面的代码显示了 RequiredIf 是如何绑定到它各自的值的:

public SelectList SubOrganisationTypeList { get; set; }
        
        [Display(Name = "Sub organisation type")]
        
        [RequiredIf(new[] {"OrganisationType,1", "OrganisationType, 9", "OrganisationType, 10"})]
        public int SubOrganisationType { get; set; }

目前,当我提交使用此自定义属性的表单时,它通过了 ModelState.IsValid 检查,我使用的非侵入性验证也没有捕捉到这一点。

如果在从属下拉列表中选择了一个值,我该如何确保错误被​​ ModelState.IsValid 检查捕获以及在未选择值时触发不显眼的验证?

最后它实际上是一个非常简单的修复,我将子下拉列表的默认值设置为 0,如下所示:

 SelectListItem defaultItem = new SelectListItem();
            defaultItem.Value = "0";
            defaultItem.Text = "Sub organisation type...";
            items.Add(defaultItem);

这导致客户端和服务器端验证都将选择验证为真。

为了修复,我再次将默认值 0 删除为空字符串,此更改如下所示:

 SelectListItem defaultItem = new SelectListItem();
            defaultItem.Value = "";
            defaultItem.Text = "Sub organisation type...";
            items.Add(defaultItem);