Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Handling ASP.NET custom Control PostData in OnInit or IPostBackDataHandler


:P

Here’s a basic question for control development. If I have a control that has maybe a single POST value that it needs to retrieve, is it safe to use code like this:

 

protected override void OnInit(EventArgs e)

{

    base.OnInit(e);

 

    //// *** Read our custom client managed Form Var that holds the tab selection

    if (this.Page.IsPostBack) 

    {

        string TabSelection = this.Context.Request.Form[HIDDEN_FORMVAR_PREFIX + this.ID];

        if (TabSelection != "")

            this._SelectedTab = TabSelection;

    }

}

 

As opposed to implementing IPostbackDataHandler:

 

public bool LoadPostData(string postDataKey, NameValueCollection postCollection)

{

    if (postDataKey == HIDDEN_FORMVAR_PREFIX + this.ID )

        this.SelectedTab = postCollection(HIDDEN_FORMVAR_PREFIX + this.ID)

}

 

public void RaisePostDataChangedEvent()

{

}

 

protected override void OnPreRender(EventArgs e)

{

    // *** Must make sure we call for custom form var name 

    this.Page.RegisterRequiresPostBack(this);

    base.OnPreRender(e);

}

 

There are definitely advantages to using IPostbackDataHandler which include being hooked into the pipeline in the right place after ViewState has loaded but before OnLoad() has fired which is necessary in many situations if ViewState is also used.

 

However, in this situation the control has a single value that’s stored in a hidden variable because the value is set from the client side. Basically it’s a client side based tab control and the variable holds the last Tab selection which is stored in the hidden variable, then posted back to the server and reassigned to the control on Postback automatically. In this case it’s a single value and it’s not going to be affected by ViewState or ControlState, so it seems kinda silly to implement this interface and override OnPreRender() just to retrieve a single value.

 

The question really is, whether it’s safe to access the Page object in OnInit(). In theory at least, the Page object gets initialized after all the controls are, so its OnInit fires after the controls. But from what I’ve seen so far, base functionality like IsPostBack and the Request object are all available so for basic operations its safe to access the Page object.

 

Any thoughts?


The Voices of Reason


 

Colin
July 26, 2006

# re: Handling ASP.NET custom Control PostData in OnInit or IPostBackDataHandler

I wrote a blog entry on the way I handle these, perhaps it will help in this case?

http://dotnet.org.za/colin/archive/2006/06/24/53678.aspx

Colin
July 26, 2006

# re: Handling ASP.NET custom Control PostData in OnInit or IPostBackDataHandler

Sorry, that probably doesn't answer your questions. Yes, it should be safe to access the "Context" property because that is HttpContext which more than likely is instantiated long before any controls are loaded.

A simple test for the two scenarios I can think of:
1. controls that are declaratively created by asp.net markup
2. controls that are dynamically added in CreateChildControls

In both cases my controls worked using this code
protected override void OnInit(EventArgs e)
{
Debug.Assert(Page != null);
Debug.Assert(Context != null);
base.OnInit(e);
}



Rick Strahl
July 26, 2006

# re: Handling ASP.NET custom Control PostData in OnInit or IPostBackDataHandler

Colin, nice post. You know I always wonder about storing vital values in ViewState which in the case of a hidden var is kind of a bad call I think. In my Tab control for example I wouldn't even think about storing the hidden value in ViewState - there's no need for it since it's persisted in the form var. I worry about this because on most of my pages I turn ViewState off.

Regarding Context - yes that's always there. Page is more what I'm worried about but it looks like core items like IsPostBack are assigned to Page before the OnInit cycle fires against controls.

But I wonder what other implications there might be.

Colin
July 26, 2006

# re: Handling ASP.NET custom Control PostData in OnInit or IPostBackDataHandler

I've also seen a case where Page is null but I can't quite remember what it was. A quick peek inside the HiddenField control using Lutz Roeder's Reflector has some interesting code.

As expected there is a value stored in viewstate and the IPostBackDataHandler to get the form value from the client. Line 2 in the Render method is:
if (this.Page != null)

Perhaps this happens in design mode? I don't know, I'll have to do a bit more experimenting

Jason Haley
July 26, 2006

# Interesting Finds: July 26, 2006


Brent Heinz
October 18, 2006

# re: Handling ASP.NET custom Control PostData in OnInit or IPostBackDataHandler

Yes, the this.Page will be null when viewing the control in design mode.

I am not 100% certain if the Render, RenderChildren, etc are called in design view however.

Personally I build custom ControlDesigners for my controls and override the GetDesignTimeHtml. I believe by doing this, there are no calls to Render in the control.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2025