ASP.Net MVC 2控制器的TryValidate不会验证列表.模型中的项目 [英] ASP.Net MVC 2 Controller's TryValidate doesn't validate the List<> items within the model

查看:80
本文介绍了ASP.Net MVC 2控制器的TryValidate不会验证列表.模型中的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何获得模型的验证,以同时验证通用列表属性中的子对象.

How do you get a model's validation to also validate child objects in a generic list property.

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

I have a model that I'm trying to validate, this is not what's being posted to the server, but a composite of some information posted, and information already on the server... for example.

 ...
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集合.

When I try to validate the model instance of B, it won't validate the Values collection for their validation attributes.

推荐答案

TryValidateModel 方法仅下降一级,因此仅检查对象的 Validation 属性键入 B ,而不是在其嵌套对象上.解决此问题的一种方法是定义您自己的 ValidationAttribute 实现:

The TryValidateModel method only goes down one level so it only checks for Validation attributes on the object of type B, not on its nested objects. One way to overcome this is to define your own implementation of a 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;
    }
}

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

Now List<A> can be validated using the attribute:

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

我还没有对上述方法的性能进行全面的测试,但是如果您遇到问题,可以使用辅助功能:

I haven't tested performance for the above approach thoroughly but if in your case that turns out to be a problem, an alternative approach is to use a helper function:

    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; 
}

这篇关于ASP.Net MVC 2控制器的TryValidate不会验证列表.模型中的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆