使用IValidatableObject的MVC3对象 - 每个TryUpdateModel()验证多次触发

时间:2011-08-03 16:00:34

标签: asp.net-mvc

我有一个从T4生成的对象类,有一个部分的SafeClass来做验证,如下所示:

public partial class Address : IValidatableObject

这个类有一个如下的Validate方法:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    //ValidationResponse is a custom struct that holds a few properties.
    ValidationResponse r = this.IsValidAddress(); //a method that does some checks

    if (!r.IsValid)
    {
        yield return new ValidationResult(r.Message, new string[] { "Address1" });
    }
}

在我的Controller的HttpPost事件中,我有一行:

if (!TryUpdateModel(_policy))
    return View(_policy);

请注意,Policy对象包含一个Person对象,该对象包含一个Address对象(所有3个片段都在同一视图中呈现;可能相关,我不知道)。

当TryUpdateModel()执行时,地址的Validate方法被调用3次。我确认它没有触发政策上的其他地址。我还验证了Controller的HttpPost方法只被调用一次。这是TryUpdateModel()的单次执行,它会激活3个Validates。

还有其他人遇到过这类事吗?有什么想法发生了什么?

2 个答案:

答案 0 :(得分:0)

我遇到了运行此代码的类似问题

        if (isPoorSpecimen)
        {

            errors.Add(new ValidationResult("Your are reporting poor specimen condition, please specify what is the reason"
                , new string[] { "SpecimenCondition", "QtyOk", "DocumentedOk", "ColdChainOk", "PackagingOK", "IsProcessable" }));
        }

它将在Html.ValidationSummary()中显示错误消息6次。 解决方案是为每个错误设置一个单一控件。

        if (isPoorSpecimen)
        {

            errors.Add(new ValidationResult("Your are reporting poor specimen condition, please specify what is the reason"
                , new string[] { "SpecimenCondition" }));
        }

答案 1 :(得分:0)

它被调用3次,因为Address实例首先被验证为独立实体,然后作为独立Person实体的成员验证,最后作为{{1}的成员验证} entity是Person实体的成员。

我建议采用以下解决方案:

1)从Policy的所有类中删除IValidatableObject并手动验证其成员:

Policy

2)或者为每个类添加一个标志以仅验证一次,因为调用中的实例是相同的:

public class Policy : IValidatableObject
{
    public Person PersonInstance { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // validate Policy...

        // then validate members explicitly
        var results = PersonInstance.Validate(validationContext);
    }
}

public class Person
{
    public Address AddressInstance { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // validate Person...

        // then validate members explicitly
        var results = AddressInstance.Validate(validationContext);
    }
}

public class Address
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // validate Address...
    }
}

希望这有帮助。