inherit from asp:validationsummary

2019-04-13 17:39发布

问题:

i have the requirement to show a nicely formatted error-message on top of the page (or control).

therefore i implemented the render method of a new created server control. the new created control inherits from ValidationSummary.

public class AgValidationSummary : ValidationSummary
{
    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        if(this.Enabled)
        {
            if (Page.IsPostBack && !Page.IsValid)
            {

my problem is now, that if an button is fired and his property CausesValidation is set to false my validationsummary will throw an exception because i ask about the Page.IsValid property (and this is only set if there was an call to Page.validate().

has somebody a solution for the problem?

回答1:

the solution is somehow easy:
just don't parse the Page.IsValid flag :) instead do something like that in your void Render(HtmlTextWriter writer):

if (!this.Enabled)
{
    return;
}

if (this.Page != null)
{
    this.Page.VerifyRenderingInServerForm(this);
}
else
{
    return;
}

var failedValidators = this.Page.Validators.OfType<BaseValidator>().Where(bv => string.Equals(bv.ValidationGroup, this.ValidationGroup) && !bv.IsValid).ToList();

if (failedValidators.Any())
{
    writer.Write(this.HeaderText);
    foreach (var failedValidator in failedValidators)
    {
        writer.Write(failedValidator.ErrorMessage);
    }
}

The reason why this works:
The control, which causes the postback, has got the information about

  1. CausesValidation
  2. ValidationGroup
  3. and other stuff

So the ASP.net-engine itself will execute the associated validators and set them to IsValid or not.

edit
To get rid of the original HeaderText (which is still rendered):

protected override void AddAttributesToRender(HtmlTextWriter writer)
{
    // overwrite to hide the original HeaderText
}


回答2:

Maybe you can save IsValid property in ViewState, and initialize it to true.

In Load, check if IsValid is null, if not null, set your IsValid in ViewState to the value in Page.IsValid.

And in Render, read IsValid from ViewState.



回答3:

I may be off track here, but can't you just wire up in your control's constructor to the page's Validate event?

If needed, you can have an internal flag that the render checks to see whether to do whatever happens next in your render code.

private bool _thePageIsBeingValidated = false;

public bool ShouldIDoMyThing
{
     get{ return (_thePageIsBeingValidated && this.Enabled && this.Page.IsPostback && this.Page.IsValid != null && this.Page.IsValid == false); }
}