开发者

MVC3 Object with IValidatableObject - Validate fires multiple times per TryUpdateModel()

I have an object class generated from a T4, with a partial SafeClass to do validation, which looks like this:

public partial class Address : IValidatableObject

This class has a Validate method like so:

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

In my Controller's HttpPost event, I have the line:

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

Note that the Pol开发者_如何学运维icy object contains a Person object, which contains an Address object (pieces of all 3 are rendered in the same view; may be relevant, I don't know).

When TryUpdateModel() executes, the Address's Validate method gets called 3 times. I verified it's not triggering for other addresses on the policy. I have also verified that the Controller's HttpPost method is only being called once. It's the single execution of TryUpdateModel() that fires off 3 Validates.

Has anybody else run into this sort of thing? Any ides what's going on?


I had encoutered similar issue running this code

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

It will show the error message 6 times in Html.ValidationSummary() . The solution is to highligt a single control per error.

        if (isPoorSpecimen)
        {

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


It is called 3 times, because the Address instance is validated first as a standalone entity, then as a member of a standalone Person entity, and finally as a member of the Person entity being a member of the Policy entity.

I would suggest the following solutions:

1) Remove IValidatableObject from all the classes but Policy and validate its members manually:

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

2) Or add a flag to each class to validate only once, since the instance across the calls is the same:

private bool validated = false;

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
    if (!validated)
    {
        validated = true;
        // do validation
    }
}

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜