是否可以将客户端验证添加到 MVC C# 的类级别验证器?

Posted

技术标签:

【中文标题】是否可以将客户端验证添加到 MVC C# 的类级别验证器?【英文标题】:Is it possible to add client validation to class level validator for MVC C#? 【发布时间】:2018-04-05 09:03:24 【问题描述】:

我有一个带有自定义验证器的嵌套模型,用于验证子元素。这种方法非常适合服务器端,但是,我还想添加客户端支持。

这是我的模型:

public class Customer
    
        public string Name  get; set;  = "";

        [AtLeastOneProperty("HomePhone", "WorkPhone", "CellPhone", ErrorMessage = "At least one phone number is required for Customer")]
        public Phone phone  get; set; 

        public Customer()
        
            phone = new Phone();
        
    
     public class Phone
     
        public string HomePhone  get; set;  = "";

        public string WorkPhone  get; set;  = "";

        public string WorkExt  get; set;  = "";

        public string CellPhone  get; set;  = "";
     

这是我的验证器:

public class AtLeastOnePropertyAttribute : ValidationAttribute, IClientValidatable
    
        private readonly string[] _properties;
        public AtLeastOnePropertyAttribute(params string[] properties)
        
            _properties = properties;
        

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        
            if (_properties == null || _properties.Length < 1)
            
                return null;
            
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);

            List<string> props = new List<string>();
            props.Add(properties[0].ToString());
            foreach (var property in _properties)
            

                validationContext = new ValidationContext(value);

                var propertyInfo = validationContext.ObjectType.GetProperty(property);
                if (propertyInfo == null)
                
                    return new ValidationResult(string.Format("unknown property 0", property));
                

                var propertyValue = propertyInfo.GetValue(validationContext.ObjectInstance, null);
                if (propertyValue is string && !string.IsNullOrEmpty(propertyValue as string))
                
                    return null;
                

                if (propertyValue != null)
                
                    return null;
                
            

            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), props);
        

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        
            var rule = new ModelClientValidationRule
            
                ErrorMessage = ErrorMessage,
                ValidationType = "atleastonerequired"
            ;
            rule.ValidationParameters["properties"] = string.Join(",", _properties);

            yield return rule;
        
    

此代码适用于服务器端验证,但是,我无法让它为我正在检查的那些属性构建客户端验证不显眼的标签。现在它正在尝试为类级别 Phone 构建标签,因为属性标签位于嵌套模型属性而不是单个属性之上。

甚至可以让它添加客户端标签吗?也许制作一个验证适配器?

【问题讨论】:

【参考方案1】:

我之前也使用过Expressive Annotations。它们允许我们指定具有布尔条件的属性,这些条件可以在客户端和服务器端触发。

【讨论】:

我使用了表达性注解,它适用于单个属性。是的,有一种方法可以Parent-to-Child,但您需要在子类中包含父 TParent 引用,在父类中包含 TChild 引用。我之所以有上面的代码是为了重用“子”类。我想我知道你的意思是通过向孩子添加一个布尔属性并检查 RequireIf("Flag == true")... 是的,根据逻辑从Phone返回布尔值并将其用作验证的表达式。

以上是关于是否可以将客户端验证添加到 MVC C# 的类级别验证器?的主要内容,如果未能解决你的问题,请参考以下文章

ASP .NET MVC在每个字段级别禁用客户端验证

在c#的mvc4中,用httpcontext.user还是session保存用户登录信息?

使用 Spring MVC 向用户呈现服务级别验证错误的好习惯

ASP.net 验证码(C#) MVC

使用 Html 助手 HiddenFor C# MVC 将模型添加到模型中

如何将业务层添加到 C# MVC 应用程序