How to persist a control property without using PostBack

For whom program in ASP.Net, since the first version you probably start to appreciate and contemporary hate the page’s StateBag, otherwise called ViewState. Without going through the particulars, to avoid loosing the article path, in few words the ViewState take care to serialize the content of the page variables into a string that is passed back to the next page request through a mechanism called PostBack.
The drama is that not all controls need ViewState, and often this persisting process is turned off to reserve memory and avoid unuseful server roundtrip.

Things changed when ASP.Net 2.0 framework has been released: a new method called ControlState was introduced for persistance. This method basically works as the ViewState, but first of all cannot be deactivated by the web page programmer, and it memorize only what is really needed (according to the override you will do in your code). Again, you can also decide for which control activate this repository and for which not.
Immediately should jumps in mind that you can even completely deactivate the ViewState and continue to be supported by the Control’s variable persistance without any matter.

That’s all true, but only in part!

So you are probably asking why I’m writing this if this isn’t the truth. As I said, it’s not true only in part. To correctly work, both ViewState and ControlState needs to embrace the PostBack technique. For whom don’t know what PostBack is, it’s a small javascript function automatically added by the framework to the rendered HTML page that take care to collect every input control’s value and to submit them to the same page through a server call. This let you restore value on the next page load for following elaboration.

Now, suppose just for a moment – as it was in my case – while I was developing a control to have a limit where you cannot use Javascript (without worrying why). What happen in this case? No javavascript = no PostBack. And then?

To avoid this kind of problem I had to use an alternative way to persist my control’s value, based always on the serialization, but persisting values in the Session object.

The serialization is the process of saving an object into a storage medium (such as a file or a memory buffer) and to transmit it across a network request.

In this way, with a couple of if inside the code, and using the same execution path used by the ControlState, I finally successfull persisted my control’s value without using PostBack.

Below an abstract of the code I used.

 

First of all I created a serializable class that you need both you want to persist values in a traditional way and with Session method.

[Serializable]
internal struct PersistedData
{
  public int test;
}

You then add a condition if you want to use the ControlState mechanism or not. This can be done in the OnInit method of our control.

if (PagingMode == PagingModeEnum.Postback)
  Page.RegisterRequiresControlState(this);
else
  LoadControlStateInSession();

It’s now necessary to add the alternative storage path in the PreRender override. You shouldn’t do anything for the ControlState since you are obliged to override the SaveControlState method.

if (PagingMode != PagingModeEnum.Postback)
  this.SaveControlStateInSession();

Finally paste the code that will perform the persistance above used.

///

/// Saves state the specified storage mechanism by
/// first serializing to a string with the LosFormatter
///
private void SaveControlStateInSession()
{
  LosFormatter output = new LosFormatter();
  using (StringWriter writer = new StringWriter())
  {
    output.Serialize(writer, this.SaveControlState());
    HttpContext.Current.Session["__" + this.UniqueID] = writer.ToString();
  }
}

///

/// Retrieves the serialized data from the Storage medium
/// as string using LosFormatter formatting.
///
private void LoadControlStateInSession()
{
  string RawBuffer = HttpContext.Current.Session["__" + this.UniqueID] as string;
  if (RawBuffer == null)
    return;   LosFormatter input = new LosFormatter();

  this.LoadControlState(input.Deserialize(RawBuffer));
}

 

The above function use the LosFormatter class that is an hidden class of the System.Web.UI namespace, used by the framework for the serialization process of the page ViewState and of the famous hidden form field __VIESTATE.

Comments are closed.