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

An ASP.NET feature I’d like to see: Control.PreserveProperty()


:P
On this page:

So in ASP.NET we have ViewState and in 2.0 we have ControlState. ViewState is a bit of a pain to use and of course you can turn it off in which case any private use of it becomes a problem. ControlState works well only for Control developers as  you have to implement a couple of specific methods that persist the data the control is interested in.

 

I find that both approaches are pretty limited. In my Web apps, I pretty much always turn ViewState off. It’s very rare that I leave it on, because of all the overhead it adds to a page. In most cases ViewState persists crap that is entirely not necessary. And if you have controls like DataGrids or lists then it really goes off the chart with how much data is persisted. Some folks like the ability to load up data once and then keep shuffling it across the wire – but I think this sort of bandwidth hogging is not really an option for a decent Web application and in many situations not practical either as data is rarely static between hits.

 

But of course if you turn ViewState off some things don’t work right or become more difficult. Good example: DataGrid paging – which starts failing or requires tricky manual assignment of the CurrentPageIndex. Now wouldn’t it be nice if you could simply tell ASP.NET to persist the CurrentPageIndex?

 

And that’s sort of where ControlState in 2.0 comes in. ControlState is supposed to address this by allowing control designers to persist properties that are crucial regardless of ViewState settings. In fact the GridView control in ASP.NET 2.0 does just that where the Page index is persisted and automatically gets restored so that the hassles of the DataGrid Paging are not an issue.

 

The drawback with controlState is that the control designer decides what to save. While that’s reasonable there often can be many other things that you might want to persist explicitly depending on the application. So if ViewState is off how can you do that?

 

A new approach 

What’s really missing is some sort of deterministic page state management mechanism. By that I mean a mechanism for the application (or a control for that matter) to easily persist data consistently.

 

It would be really nice if there was an easier and more deterministic way to persist values in ASP.NET. One way that I think would be nice is to have a PreserveProperty() method on the control class that could automatically store and restore a value on a control which simplify persistence greatly and allow tight control over exactly what gets persisted both on the control as well as the application level.

 

I built something this in Web Connection (my Fox Web framework) and I’m really finding that this gives me the best of both worlds with a very easy interface that I don’t have to think about like you do with ViewState. And to boot that's the mechanism I ultimately use to persist ViewState in that framework as well. 

 

The way it works is that I have a PreserveProperty method on the control (maybe it should be PreserveValue() in ASP.NET because I’d want both Fields and Properties). So you might say: 

this.TextBox1.PreserveProperty("ForeColor");
this.PreserveProperty("CurrentCustomerPk");

in Page_Load() which would add these properties to a collection on the respective controls. Then anytime after you could simply read the value of the property or it would already be assigned (as part of ViewState processing).

 

Notice that you can persist application level values on the form like a CustomerPk for example. Think about it - that's a heck of a lot nicer than adding a hidden form variable or using ViewState to track the state of a value, no?

 

Then after rendering is complete, the control class runs through each control and the preserved properties and persists them (into mandatory viewstate or controlstate or some new value on the page).

 

The framework would then automatically persist that property and restore it on the next postback. It basically would work the same way as ViewState does in that it would write out values to some internal statebag and then retrieve it early on in the page cycle (same time that ViewState gets restored). Each control would manage it’s own statebag.

 

What this does it a) makes it very easy to deterministically have ASP.NET persist values and restore them without explicitly having to use ViewState and the Null check blocks that go with it and b) would be always available regardless of EnableViewState settings and c) it would allow you to specifically determine what to persist so you’d only persist what you ask for and no more. Unlike ViewState, which has to figure out everything that is not in its default statehas changed on a control.

 

Note that this would allow you to store away anything even though it’s Control.PreserveProperty(), because this would exist also on the Page class. As long as it’s a property/field on the Page object it could persist. Of course the same rules as ViewState would apply: Objects must be serializable in order to persist.

 

It seems the mechanics to do this are already built into the Controls anyway because roughly that is what ViewState does. But by exposing the underlying mechanism, the low level feature that says ‘preserve this property and restore it automatically’ we gain a lot of functionality in our apps to tightly control exactly what gets persisted and restored and easily.

 


The Voices of Reason


 

Bertrand
December 22, 2005

# re: An ASP.NET feature I’d like to see: Control.PreserveProperty()

It's a nice idea, and probably something that could be built today by slightly changing the signature.
How about having a persister control on the page and do something like Persister.Persist(SomeControl, "SomeProperty")?

Rick Strahl
December 22, 2005

# re: An ASP.NET feature I’d like to see: Control.PreserveProperty()

Well, I've actually implemented this functionality on my custom controls, so yes you can definitely do this on your own.
Another approach would be a behavior object that could be attached to a control.

But it sure would be much nicer if it was natively built in since we can't natively create base class functionality that all controls inherit.

Bertrand
December 22, 2005

# re: An ASP.NET feature I’d like to see: Control.PreserveProperty()

Yes, that's why I was suggesting a separate control so that existing controls can take advantage of it. You could even make it declarative like this:
<persister>
<persist control="myControl">
<property name="SomeProperty"/>
</persist>
</persister>

Rick Strahl
December 24, 2005

# re: An ASP.NET feature I’d like to see: Control.PreserveProperty()

Well, there are a few problems with an external control. First you have to put a control on the page <g>. But more importantly an external control doesn't have access to protected members of the page or the controls. So if you're trying to protect something that is internal to the control or page, you can't use the external control.

To be really useful this has to be either built-in which is the preferred mechanism, or needs to be added to each control. Each control needs to manage its own state for this.


Rick Strahl's WebLog
December 26, 2005

# Implementing an ASP.NET PreserveProperty Control

A couple of days ago I posted about having PreserveProperty functionality in ASP.NET. Today I'll look at implementing a custom control that implements this functionality. The control allows saving and restoring of property values automatically and declaratively without ViewState being enabled. This article discusses the control functionality and implementation in some detail. If you're new to Server Control development this article covers a few important topics such as exposing collections as child controls, using custom attributes for managing control visibilty etc.

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