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。