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

查看:182
本文介绍了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的模型实例,它不会验证值集合及其验证属性。

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

推荐答案

TryValidateModel 方法仅下降一个级别,因此仅检查验证属性类型 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;
    }
}

现在列表&LT; A&GT; 可以使用属性进行验证:

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不验证列表&LT;&GT;在模型内的物品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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