Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Building a PreserveProperty Control in ASP.NET 2.0 : Page 2

Find out how to create a deterministic and declarative property persistence control that works without ViewState and provides transparent access to persisted properties and fields on your ASP.NET controls and pages.

Introducing the PreservePropertyControl
The PreservePropertyControl is an ASP.NET 2.0 custom server control. The downloadable code for this article also contains an ASP.NET 1.1 version of the source courtesy of Peter Bromberg who ported it back to 1.1. I used ASP.NET 2.0 mainly to take advantage of generics for the persisted properties rather than implementing a custom collection. .NET 2.0 makes it a cinch to create strongly-typed collections with generics. You can then use the designer to edit these collections using the default Collection editor. Another 2.0 feature, ControlState, provides the default storage mechanism for the PreserveProperty control. ControlState makes it easy to persist an internal structure without having to worry about encoding the structure for embedding into the page.

I implemented the control as a server control that can be defined on the page declaratively and has designer support. For example you can declare the control like this:

<ww:PreservePropertyControl ID="Persister" runat="server"> <PreservedProperties> <ww:PreservedProperty ID="PreservedProperty1" runat="server" ControlId="btnSubmit" Property="ForeColor" /> <ww:PreservedProperty ID="PreservedProperty2" runat="server" ControlId="__Page" Property="CustomerPk" /> </PreservedProperties> </ww:PreservePropertyControl>

You can do this with script markup inside of your ASP.NET page, or use the designer and the default collection editor to enter the preserved properties with Visual Studio. To persist a value, you specify the control's UniqueID and the property or field name to persist. You can persist control values as well as values on the Page object as shown with the __Page ControlId above.

Of course, you can also use code to accomplish the same thing.

protected PreservePropertyControl Persister=null; protected void Page_Load(object sender, EventArgs e) { this.Persister=new PreservePropertyControl(); this.Persister.ID = "Persister"; this.Controls.Add(Persister); this.Persister.PreserveProperty( this.btnSubmit, "ForeColor"); this.Persister.PreserveProperty( this, "CustomerPk"); }

When using code, it's more efficient to pass an actual control reference rather than a string ID—the control caches the control reference and uses it later in the page cycle to write the values into its storage container.

ControlState is accessible only inside of a control and not on the Page level.
Note that you get a lot of flexibility with this mechanism, and you can basically store anything in this state container as long as you can reference it through a control instance. Because the Page object is also a control you can attach a Protected property for anything you want persisted. It's quite convenient, for example, to add a Pk reference to a page so you can keep track of your current edit context without requiring ViewState or a hidden variable.

You can even store entire objects. Like ViewState, you can store any serializable object in the PreservePropertyControl. The nice thing about this approach is you set up the PreserveProperty() call once and after that you can just reference the property. So if you persist the CustomerPk as shown above you can simply reference the CustomerPk property on the page and always get the correct value back without having to explicitly access a state mechanism. You can just say this.CustomerPk and the value will be up to date!

This approach is even easier than ViewState because it eliminates the need to talk to the state container at all. You don't need to access a statebag, double-check for null values, etc. The control manages that for you.

Control developers can also use the control internally to map their own properties by using a private copy of the control.

public class CustomControl : Control { PreservePropertyControl Persister = null; protected string value = null; protected override void OnLoad(EventArgs e) { this.Persister = new PreservePropertyControl(); this.Persister.ID = "__" + this.ID; this.Persister.StorageMode = PropertyStorageModes.HiddenVariable; this.Persister.PreserveProperty( this,"value"); this.Controls.Add(this.Persister); base.OnLoad(e); } }

Once this is in place the control developer doesn't have to keep persisting values into any special store like ViewState["value"] or a custom container, but can simply reference the property as usual, all without ViewState being active.

You can check out the control and a small sample page that demonstrates the functionality by downloading the source code provided with this article. The .zip file contains both the 2.0 and 1.1 versions.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date