Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Beginner's Tutorial - Understanding ControlState in ASP.NET

0.00/5 (No votes)
17 Feb 2012 3  
A Beginner's Tutorial - Understanding ControlState in ASP.NET

Introduction

This article aims at understanding why and when we need to have ControlState for the state management. We also try to understand the same with a very basic implementation of control state.

Background

By default, the ASP.NET page has EnableViewState property true. This makes ASP.NET automatically keep track of state of all the controls present on the page. Now if I am working on a web page where I know all the controls will be dynamically bound to some data on each postback, I don't have to keep track of the old information for the controls. So I might decide to turn it off. Now this is a perfectly good choice for the page developer but things could get messy if the same page contains a custom control and that custom control is using ViewState to manage the data inside the control.

The main focus here is to look at from a Control Developers point of view. How can I write controls that are immune to the controls users' action, i.e., it will work in any case whether ViewState is ASP.NET enabled or disabled.

Using the Code

ASP.NET already provides a mechanism for such scenarios and it's called ControlState. Here we will simply try to see the right way of writing a custom control with proper ControlState and ViewState management.

Suppose we have a very simple custom control that displays a couple of welcome messages to the user. If I go and create a custom control project to facilitate this, I will get something like:

[ToolboxData("<{0}:WebCustomControl runat="server"></{0}:WebCustomControl>")]
public class WebCustomControl : WebControl
{
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Localizable(true)]
    public string Text
    {
        get
        {
            String s = (String)ViewState["Text"];
            return ((s == null) ? String.Empty : s);
        }

        set
        {
            ViewState["Text"] = value;
        }
    }

    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Localizable(true)]
    public string Text2
    {
        get
        {
            String s = (String)ViewState["Text2"];
            return ((s == null) ? String.Empty : s);
        }

        set
        {
            ViewState["Text2"] = value;
        }
    }

    protected override void RenderContents(HtmlTextWriter output)
    {
        output.Write(Text);
        output.Write("<br/>");
        output.Write(Text2);
        output.Write("<br/>");
    }       
}

A very basic control that is rendering two welcome messages and the user of the control has an option of setting these messages from outside, which could be from a database call or reading from a file. The user will perhaps do this only once and will expect our control to remember these strings. So let's say the user of the controls is doing something like:

if (IsPostBack == false)
{
    WebCustomControl_1.Text = "This is a dummy Text";
    WebCustomControl_1.Text2 = "This is another dummy Text";
}

Now for the first run, he will do the property setting and from next time onwards, he leaves it upto the control to render these things. Now the page still has EnableViewState property set to "true". So if we run the page and do postback, we will observe the expected behavior. Let's look at what user will see:

Sample Image - control state snapshot

Now if the user disables the viewstate for the page or even for our custom control when a postback occurs:

Sample Image - control state snapshot

The values are gone, the reason being our control depends on ViewState to function and we need to remove this dependency to controlState so that even in this scenario, our control will continue to work.

So let us use Control State for one line of text and not for other (purely to see how these things differ and we can compare the right way and the wrong way in the same piece of code, ideally all the controls information should use ControlState mechanism).

What we need to do here is, we have to override the OnInit method and call the RegisterRequiresControlState method during initialization. Then we have to override the SaveControlState and LoadControlState methods. So let us see how we do that for using ControlState for Text property of our control.

protected override void OnInit(EventArgs e)
{
    Page.RegisterRequiresControlState(this);
    base.OnInit(e);
}

protected override void LoadControlState(object savedState)
{
    Text = (string)savedState;
}

protected override object SaveControlState()
{
    return Text;
}

Now we have the first property of our control using controlState and the second one not using it. Now on postback, the output is:

Sample Image - control state snapshot

Look at the code to see the difference. The right way would be the way ControlState is being used for the first property, it should be used for all the controls inside a custom control.

Points of Interest

To summarize, we saw what is the control state and how to enable it in custom controls. The control state takes away the decision of a developer whether to use ViewState or not. Whenever we want to use the control state, you should think whether to implement it or give the decision of how to save the state information to the developers that use your control. The second choice is more preferable as it decreases the dependency on something that Page can set.

History

  • 17 Feb 2012: Explanatory tutorial on ControlState

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here