ASP.NET Control State for Custom Server Controls

State management is a perennial challenge for any web development framework – once a page is refreshed any data on the page (such as text already entered in textboxes) must be persisted using some method. Traditionally ASP.NET solves this problem using View State which inserts text directly into the html of the page which can then be read by the server when the page is posted to the server. This solution works well in most circumstances but the one major issue is performance – View State adds a large payload to each page request and will slow the ASP.NET site/app down. The issue is especially acute when using ASP.NET AJAX since there are numerous background hits on the server and each of which needs to contain the full View State payload.

Control State is designed to be a much more lightweight store of data than view state . Control State is designed to store   data a control is currently using. Technically, control state works in the same manner as view state—storing serializable data that’s placed in a hidden field when a page is rendered. ASP.NET actually puts   view state and control state data into the same hidden field. The only major difference is that control state is unaffected by the EnableViewState property, therefore even if EnableViewState is set to false, acontrol can still store and retrieve data from  control state.

Since control state cannot be disabled, you will need to  carefully restrict the amount of information stored. Normally, it is limited to something critical such as the current page index or else a data key value. To use control state in  a custom server control, you   begin by overriding the OnInit() method and the calling Page.RegisterRequiresControlState() to notify ASP.NET that the control needs to access control state.

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

Unlike view state, control state cannot be accessed  directly through a collection and you must override two methods:  LoadControlState() and SaveControlState(). These methods use a slightly irregular pattern. The overall idea is that you need to take any control state which has been serialized by the base class and then combine that with an object which contains your new serializable object. You can do this using the System.Web.Pair class, as shown below:

string myData;
protected override object SaveControlState()
{
// Get state from the base class.
object baseStateObj = base.SaveControlState();
// Combine  with the state object you wish to store
// and then return the final object.
return new Pair(baseStateObj, myData);
}

This technique will enable you to only store  a single object. For storing several items of information, consider creating a custom class which encapsulates all these details (and ensure it includes the Serializable attribute). An alternative method is to  create a chain of Pair objects:

private string strData;
private int integerData;
protected override object SaveControlState()
{
// Get state from the base class.
object baseStateObj = base.SaveControlState();
// Combine with the state objects you want to store,
// and return the final object.
Pair pairA = new Pair(strData, integerData);
Pair pairB = new Pair(baseStateObj, pairA);
return pairB;
}

Continues…

Nesting Server Controls in ASP.NET

A common scenario in a repeating data display would be like this:

Category Name   Product 1   Product 2   Product 3

The data would repeat, listing each category name, and then, under that category, each product in that particular category. In Classic ASP, there were several ways of doing this, of which, arguably the most common approach is/was a For/Next Loop with a Recordset.

Now, with the advent of ASP.Net, we can acutually Nest repeating controls (DataList, Repeater) to do this. I’ll admit, even if you’ve had a little relational database experience, this will, at first be a little daunting – but once you fully understand it, it seems extremely logical.

In this tutorial, we’re going to use a DataList control, the SQL Managed Provider, and the Northwind Database (Categories and Products tables). we could have just as easily used a Repeater control, with different formatting. Here are the steps to produce this scenario:

    In the HTML:

  1. Create/instantiate one DataList control (ID=dlCategories), with an ItemTemplate (Container.DataItem=CategoryName)
  2. Inside that ItemTemplate, create/instantiate another DataList control, with an ItemTemplate(Container.DataItem=ProductName)
    The difference here is that we’re going to add a DataSource (datasource=’<%# Container.DataItem.Row.GetChildRows(“myrelation”) %>’) – Don’t worry about what this means – it’s in the code section

Continues…