是否可以将客户端验证添加到 MVC C# 的 class 级别验证器?
Is it possible to add client validation to class level validator for MVC C#?
我有一个带有自定义验证器的嵌套模型,用于验证子元素。这种方法对服务器端很有效,但是,我也想添加客户端支持。
这是我的模型:
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;
}
}
此代码适用于服务器端验证,但是,我无法让它为我正在检查的那些属性构建客户端验证不显眼的标签。现在它正在尝试构建 class 级别 Phone 的标签,因为属性标签位于嵌套模型 属性 而不是单个 属性.[=13= 之上]
是否可以让它添加客户端标签?也许制作一个验证适配器?
我以前用过Expressive Annotations。它们允许我们使用可以在客户端和服务器端触发的布尔条件指定属性。
我有一个带有自定义验证器的嵌套模型,用于验证子元素。这种方法对服务器端很有效,但是,我也想添加客户端支持。
这是我的模型:
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;
}
}
此代码适用于服务器端验证,但是,我无法让它为我正在检查的那些属性构建客户端验证不显眼的标签。现在它正在尝试构建 class 级别 Phone 的标签,因为属性标签位于嵌套模型 属性 而不是单个 属性.[=13= 之上]
是否可以让它添加客户端标签?也许制作一个验证适配器?
我以前用过Expressive Annotations。它们允许我们使用可以在客户端和服务器端触发的布尔条件指定属性。