Checking if a page IsValid even when CausesValidation is false

14,450

I'd suggest you simply use your validators with the EnableClientScript option set to false.

This way, you will be able to call

if (this.Page.IsValid)

in your code.

If you want to validate a specific validation group, just use this line in server-side:

Page.Validate("ValidationGroupName")

Look at these examples of group validation

Share:
14,450
Robin Day
Author by

Robin Day

Software Developer... Nothing more, nothing less.

Updated on September 14, 2022

Comments

  • Robin Day
    Robin Day over 1 year

    I need to check the value of Page.IsValid on every load/postback of a page in order to perform some other logic.

    However, IsValid cannot be called if Page.Validate() has not been called.

    Page.Validate() will not be called if the control that posted back had CausesValidation set to false.

    If I call Page.Validate() myself, it causes all the Validators on the page to display.

    I currently have two solutions to this problem.

    First method, I use a try catch around IsValid. I catch the exception that will occur if validation has not occurred. I then call Page.Validate, check the value of IsValid, then loop through all the Validators to mark them all as Valid so they do not appear on the page.

    bool isValid = false;
    
    try
    {
        isValid = this.IsValid;
    }
    catch (System.Web.HttpException exception)
    {
        if(exception.Message == "Page.IsValid cannot be called before validation has taken place. It should be queried in the event handler for a control that has CausesValidation=True and initiated the postback, or after a call to Page.Validate.")
        {
            //Validation has NOT occurred so run it here, store the result, then set all the validators to valid.
            this.Validate();
            isValid = this.IsValid;
    
            foreach (IValidator validator in this.Validators)
            {
                validator.IsValid = true;
            }
        }
    }
    

    Second method, is to use reflection to get the field _validated from the underlying page itself. Then I do the same as the first method in calling Validate if the page hasn't been validated and then resetting all the Validators afterwards.

    bool isValidated = (bool)typeof(Page).GetField("_validated", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(this);
    
    bool isValid = false;
    
    if (isValidated)
    {
        isValid = this.IsValid;
    }
    else
    {
        this.Validate();
        isValid = this.IsValid;
    
        foreach (IValidator validator in this.Validators)
        {
            validator.IsValid = true;
        }
    }
    

    I do not like either of this solutions as I don't like coding by exceptions and I don't like using reflection to get at the Validated property as there must have been some reason it was kept private in the first place.

    Does anyone else have any better solutions or any ideas?