MVC 自定义验证字符串数组客户端
MVC Custom Validation String Array Client Side
有采用数组参数的自定义 MVC 验证器的示例,但只有服务器端 - none 其中显示了使用数组参数实现客户端的示例。
问题不是在 html data- 属性中输出数组的内容,而是输出 "System.String[]":
data-val-total-propertynames="System.String[]"
这是我的属性 class:
public class TotalAttribute : ValidationAttribute, IClientValidatable
{
private String[] PropertyNames { get; set; }
public TotalAttribute(String[] propertyNames)
{
PropertyNames = propertyNames;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
float total = 0;
foreach (var propertyName in PropertyNames)
total += (float)context.ObjectInstance.GetType().GetProperty(propertyName).GetValue(context.ObjectInstance, null);
if (total != (float)value)
return new ValidationResult(FormatErrorMessage(context.DisplayName), new[] { context.MemberName });
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = ErrorMessageString,
ValidationType = "total",
};
rule.ValidationParameters["propertynames"] = PropertyNames;
yield return rule;
}
}
这里是在模型中实现的:
[Total(new string[] { "SomeOtherField1", "SomeOtherField2" }, ErrorMessage = "'Line12Balance' must equal total of 'SomeOtherField1' and 'SomeOtherField2'")]
public decimal? Line12Balance { get; set; }
这是 html data-val 属性输出:
data-val-total-propertynames="System.String[]"
我做错了什么?
你得到 "System.String[]"
字符串是因为 ValidationParameters["propertynames"]
的值是通过调用 ToString
写入的,所以 string[]
变量 returns "System.String[]"
在这种情况下。如果你需要输出特定的值,你需要在你的验证属性中自己格式化它。例如,更改
rule.ValidationParameters["propertynames"] = PropertyNames;
到
rule.ValidationParameters["propertynames"] = string.Join(",", PropertyNames);
你会得到
data-val-total-propertynames="SomeOtherField1,SomeOtherField2"
正如 Alexander 在他的回答中提到的,您遇到的问题是 string[]
没有自己的 ToString()
实现,而是使用基础 object.ToString()
实现,它只显示对象的类型而不是数组的内容。
所以你必须以某种方式序列化你的字符串数组,以便它可以存储在一个字符串中,然后在你的客户端解析 JavaScript。
如果您已经在您的解决方案中使用 JSON.Net(很多都是),您也可以通过 JSON 在服务器端序列化数组,然后解析 JSON客户端。
即服务器端:
rule.ValidationParameters["propertynames"] = JsonConvert.SerializeObject(PropertyNames);
客户端:(
$.validator.addMethod('rule', function(value, element, params) {
var propertynames = JSON.parse(params.propertynames);
// do your validation
});
这使您不必在参数中转义 commas/delimiters。
有采用数组参数的自定义 MVC 验证器的示例,但只有服务器端 - none 其中显示了使用数组参数实现客户端的示例。
问题不是在 html data- 属性中输出数组的内容,而是输出 "System.String[]":
data-val-total-propertynames="System.String[]"
这是我的属性 class:
public class TotalAttribute : ValidationAttribute, IClientValidatable
{
private String[] PropertyNames { get; set; }
public TotalAttribute(String[] propertyNames)
{
PropertyNames = propertyNames;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
float total = 0;
foreach (var propertyName in PropertyNames)
total += (float)context.ObjectInstance.GetType().GetProperty(propertyName).GetValue(context.ObjectInstance, null);
if (total != (float)value)
return new ValidationResult(FormatErrorMessage(context.DisplayName), new[] { context.MemberName });
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = ErrorMessageString,
ValidationType = "total",
};
rule.ValidationParameters["propertynames"] = PropertyNames;
yield return rule;
}
}
这里是在模型中实现的:
[Total(new string[] { "SomeOtherField1", "SomeOtherField2" }, ErrorMessage = "'Line12Balance' must equal total of 'SomeOtherField1' and 'SomeOtherField2'")]
public decimal? Line12Balance { get; set; }
这是 html data-val 属性输出:
data-val-total-propertynames="System.String[]"
我做错了什么?
你得到 "System.String[]"
字符串是因为 ValidationParameters["propertynames"]
的值是通过调用 ToString
写入的,所以 string[]
变量 returns "System.String[]"
在这种情况下。如果你需要输出特定的值,你需要在你的验证属性中自己格式化它。例如,更改
rule.ValidationParameters["propertynames"] = PropertyNames;
到
rule.ValidationParameters["propertynames"] = string.Join(",", PropertyNames);
你会得到
data-val-total-propertynames="SomeOtherField1,SomeOtherField2"
正如 Alexander 在他的回答中提到的,您遇到的问题是 string[]
没有自己的 ToString()
实现,而是使用基础 object.ToString()
实现,它只显示对象的类型而不是数组的内容。
所以你必须以某种方式序列化你的字符串数组,以便它可以存储在一个字符串中,然后在你的客户端解析 JavaScript。
如果您已经在您的解决方案中使用 JSON.Net(很多都是),您也可以通过 JSON 在服务器端序列化数组,然后解析 JSON客户端。
即服务器端:
rule.ValidationParameters["propertynames"] = JsonConvert.SerializeObject(PropertyNames);
客户端:(
$.validator.addMethod('rule', function(value, element, params) {
var propertynames = JSON.parse(params.propertynames);
// do your validation
});
这使您不必在参数中转义 commas/delimiters。