ASP.Net MVC 2控制器的TryValidate不会验证列表.模型中的项目 [英] ASP.Net MVC 2 Controller's TryValidate doesn't validate the List<> items within the model
问题描述
如何获得模型的验证,以同时验证通用列表属性中的子对象.
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屋!