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

C# 是否可以将客户端验证添加到MVC的类级验证程序中?,c#,jquery,asp.net-mvc,validation,unobtrusive-validation,C#,Jquery,Asp.net Mvc,Validation,Unobtrusive Validation,我有一个嵌套模型,带有一个自定义验证器,用于验证子元素。这种方法对于服务器端非常有效,但是,我还想添加客户端支持 这是我的模型: public class Customer { public string Name { get; set; } = ""; [AtLeastOneProperty("HomePhone", "WorkPhone", "CellPhone", ErrorMessage = "At least one phone number

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

这是我的模型:

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;
        }
    }
公共类AtLeastOnePropertyAttribute:ValidationAttribute,IClientValidable
{
私有只读字符串[]\u属性;
公共AtLeastOnePropertyAttribute(参数字符串[]属性)
{
_属性=属性;
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
if(_properties==null | |_properties.Length<1)
{
返回null;
}
PropertyDescriptorCollection属性=TypeDescriptor.GetProperties(值);
列表道具=新列表();
添加(属性[0].ToString());
foreach(变量属性在_属性中)
{
validationContext=新的validationContext(值);
var propertyInfo=validationContext.ObjectType.GetProperty(属性);
如果(propertyInfo==null)
{
返回新的ValidationResult(string.Format(“未知属性{0}”,属性));
}
var propertyValue=propertyInfo.GetValue(validationContext.ObjectInstance,null);
if(propertyValue为string&!string.IsNullOrEmpty(propertyValue为string))
{
返回null;
}
if(propertyValue!=null)
{
返回null;
}
}
返回新的ValidationResult(FormatErrorMessage(validationContext.DisplayName),props);
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
var规则=新ModelClientValidationRule
{
ErrorMessage=ErrorMessage,
ValidationType=“atleastonerequired”
};
rule.ValidationParameters[“properties”]=string.Join(“,”,_properties);
收益率-收益率规则;
}
}
这段代码适用于服务器端验证,但是,我无法让它为我正在检查的那些属性构建客户端验证不引人注目的标记。现在它正在尝试为类级别的电话构建标记,因为属性标记位于嵌套模型属性而不是单个属性之上


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

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

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

我使用了表达性注释,它适用于单个属性。是的,有一种方法,但是您需要在子类中包含父TParent引用,在父类中包含TChild引用。我之所以使用上面的代码是为了重用“child”类。我想我知道你在子对象中添加一个布尔属性并检查它的RequireIf(“Flag==true”)…是的,根据逻辑从Phone返回布尔值并将其用作表达式进行验证。我使用了表达性注释,它对单个属性很有效。是的,有一种方法,但是您需要在子类中包含父TParent引用,在父类中包含TChild引用。我之所以使用上面的代码是为了重用“child”类。我想我知道你在子对象中添加一个布尔属性并检查它的RequireIf(“Flag==true”)…是的,根据逻辑从Phone返回布尔值,并将其用作表达式进行验证。