c# - ASP.Net MVC 2 Controller 的 TryValidate 不验证模型中的 List<> 项

标签 c# asp.net-mvc-2 asp.net-mvc-2-validation

如何让模型的验证也验证通用列表属性中的子对象。

我有一个我正在尝试验证的模型,这不是发布到服务器的内容,而是发布的一些信息和服务器上已有的信息的组合...例如。

 ...
public class A {
   [Required]
   public string Property1 { get; set; }
}
...
public class B {
   public List<A> Values { get; set; }
}
...
    if (!TryValidateModel(instanceofB))
    {
        //this should fire, as one of A inside B isn't valid.
        return View(instanceofB);
    }

当我尝试验证 B 的模型实例时,它不会验证 Values 集合的验证属性。

最佳答案

TryValidateModel方法只下降一级,所以它只检查 Validation B 类型对象的属性,而不是在它的嵌套对象上。克服这个问题的一种方法是定义您自己的 ValidationAttribute 实现。 :

public class ListValidationAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        IEnumerable enumerable = value as IEnumerable;
        // If the input object is not enumerable it's considered valid.
        if (enumerable == null)
        {
            return true;
        }
        foreach (object item in enumerable)
        {
            // Get all properties on the current item with at least one
            // ValidationAttribute defined.
            IEnumerable<PropertyInfo> properties = item.GetType().
                GetProperties().Where(p => p.GetCustomAttributes(
                typeof(ValidationAttribute), true).Count() > 0);
            foreach (PropertyInfo property in properties)
            {
                // Validate each property.
                IEnumerable<ValidationAttribute> validationAttributes =
                    property.GetCustomAttributes(typeof(ValidationAttribute),
                    true).Cast<ValidationAttribute>();
                foreach (ValidationAttribute validationAttribute in
                    validationAttributes)
                {
                    object propertyValue = property.GetValue(item, null);
                    if (!validationAttribute.IsValid(propertyValue))
                    {
                        // Return false if one value is found to be invalid.
                        return false;
                    }
                }
            }
        }
        // If everything is valid, return true.
        return true;
    }
}

现在List<A>可以使用属性进行验证:

public class B
{
    [ListValidation]
    public List<A> Values { get; set; }
}

我还没有彻底测试上述方法的性能,但如果在您的情况下证明这是一个问题,另一种方法是使用辅助函数:

    if (!ValidateB(instanceofB))
    {
        //this should fire, as one of A inside B isn't valid.
        return View(instanceofB);
    }

...

public bool ValidateB(B b)
{
    foreach (A item in b.Values)
    {
        if (!TryValidateModel(item))
        {
            return false;
        }
    }
    return true; 
}

关于c# - ASP.Net MVC 2 Controller 的 TryValidate 不验证模型中的 List<> 项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4465432/

相关文章:

c# - 如何验证 MVC2 表单中的多选?

c# - 检查 'success' 是否为 null 算作 "Double use of variables"?

sql - Linq 到 Sql,System.Exception 转换无效

c# - 重新排序数据网格的列后如何获得新的列顺序?

asp.net-mvc-2 - Html.DescriptionFor<T>

c# - 如何在 EditorFor 中访问 C# 模型属性

asp.net-mvc - ASP.NET MVC Html.ValidationSummary(true) 不显示模型错误

c# - MVC 2 - 如何在创建方法中排除多列

c# - 使用代码优先的 EF 4.1 中的 TPH 继承映射问题

c# - 禁用 View (ASP.NET MVC) 中的所有控件(文本框、复选框、按钮等)