ASP and .Net Coding Techniques
Page 5 - "State" Rights? Dear God! Is it a Confederacy All Over Again? 2006-04-03
| Table of Contents: |
| Rate This Article: | Add This Article To: |
( Page 5 of 5 )
Added">
A New State is Added
Now that you are one with state management, let's shoot for total nirvana: what's new in 2.0?
One weakness of ViewState is that it can be turned off by a page developer. Every webcontrol is equipped with an EnableViewState property that allows a page developer to turn off that control's ability to maintain state between postbacks. Furthermore, an ASPX page has an EnableViewState directive that can be turned on or off at the top of a page. If you think that's not enough, it can also be turned off in the Web.Config file, affecting the entire site. Oh yeah, and that's right kids, you can also turn it off in the Machine.Config, affecting the entire server.
Depending on how they were written, some controls may be rendered pretty useless. The result is that the all-or-nothing approach has put page developers at the mercy of of control developers, to some extent.
ASP.NET 2.0 introduces something called ControlState. For the most part, it works almost identically to ViewState, with a couple of exceptions. The most important difference is that it has no direct-access variable like ViewState; ControlState can only be used through method-overrides.
The Control class contains two overridable methods, appropriately called SaveControlState and LoadControlState. ASP.NET handles the calling of these methods within the page life cycle in the exact same way it handles the ViewState methods. In fact, you can apply everything I just taught you about the ViewState methods to the ControlState methods.
As I said however, there is no actual ControlState variable, so you must override the SaveControlState and LoadControlState methods to use this functionality.
OK, that's easy enough. But what is it good for? Well for starters, ControlState cannot be turned off by page developers, so we no longer have the all-or-nothing situation. Any property variables we choose to store using SaveControlState and LoadControlState are guaranteed to be persisted, even if a page developer sets EnableViewState to false at any level: control, page, site, or server.
This is important for control developers to understand. You must use good judgment when determining which properties to persist in ViewState and which to persist in ControlState. The general rule of thumb is this: properties whose persistence is essential for the control's proper operation would use ControlState — maybe data, or some behavior-related properties. Appearance-related or lower-priority properties would stay in ViewState, and the page developer would need to worry about repopulating those themselves, should they turn off ViewState.
Before you go running off to start using ControlState, only to find out that it does not work, I should tell you that controls that use it must register themselves as needing it. This is accomplished by overriding the OnInit event of the control and calling the RegisterRequiresControlState method of the Page object, like so:
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
Page.RegisterRequiresControlState(Me)
End Sub
That's it! All other aspects of ControlState work just like its cousin, ViewState. In fact, storage happens the same way too; ControlState is stored in a new hidden text field called __ControlState.
ControlState in Action
The sample webcontrol in the downloadable code displays a very simple (and pretty useless) form with two labels and two textboxes. We have a caption and textbox for 'first name' and a caption and textbox for 'last name'. I set up two properties for the label captions, appropriately called FirstNameCaption and LastNameCaption (sound familiar?).
Protected _FirstNameCaption As String = "First name:"
Public Property FirstNameCaption() As String
Get
Return _FirstNameCaption
End Get
Set(ByVal value As String)
_FirstNameCaption = value
Me.ChildControlsCreated = False
End Set
End Property
Public Property LastNameCaption() As String
Get
If CType(ViewState("LastNameCaption"), Object) Is Nothing Then
Return "Last name:"
End If
Return CType(ViewState("LastNameCaption"), String)
End Get
Set(ByVal Value As String)
ViewState("LastNameCaption") = Value
Me.ChildControlsCreated = False
End Set
End Property
The LastNameCaption property uses the conventional method of persistence using the now-all-too-familiar ViewState variable. However, the FirstNameCaption property exposes a member variable called _FirstNameCaption, which, unless we write some additional code, is not persisted.
As you can probably guess by now, I override the SaveControlState and LoadControlState methods to persist this variable.
Protected Overrides Function SaveControlState() As Object
Dim state() As Object = New Object(2) {}
state(0) = MyBase.SaveControlState()
state(1) = _FirstNameCaption
Return state
End Function
Protected Overrides Sub LoadControlState(ByVal savedState As Object)
If savedState IsNot Nothing Then
Dim state() As Object = CType(savedState, Object())
MyBase.LoadControlState(state(0))
_FirstNameCaption = CType(state(1), String)
End If
End Sub
To test what I've done, I set up a sample web site that uses this control (also included in the downloadable code). On a webform, I drop an instance of our control, as well as two other buttons. The first button is labeled "Change Values," and the second, "Perform Postback."
In the Click event of the first button, I place the following code:
TestControl1.FirstNameCaption = "Enter your first name:" TestControl1.LastNameCaption = "Enter your last name:"
ControlState, they persist just fine between postbacks.
Now, we turn the EnableViewState property of the control to false and re-run the site. Pressing the first button changes the caption values as expected. However, if we press the "Perform Postback" button, you see only the 'last name' caption change back. It was not stored in ViewState because we turned it off. That property reverted back to the default state coded in the control's class. The 'first name' caption, however, maintained its change properly. This property is stored in ControlState and its persistence cannot be messed with.
I urge you to download the complete code and watch it in action. Using ControlState gives control developers more power and flexibility in design and how controls behave in a page.
However, I also want to instill in you the importance of using good judgment when designing your controls. Don't use ControlState for everything. Remember, ControlState is stored in the same type of encoded hidden text field that ViewState uses. Using ViewState wisely was a must, to avoid unnecessary bloating; the same applies to ControlState now.
As a control developer, you should give the page developer the choice of storing certain properties in an alternative fashion, should he decide that the page's ViewState has the potential of becoming excessively large. Design and program wisely, and allow ASP.NET's state management mechanism to be the life saver it was designed to be — and not the root of unfounded criticism that it does not deserve.
Download the source code that accompanies this article
![]() |
|


