Real-world applications often need rich controls. The family of built-in ASP.NET controls provides lots of functionality but arent as rich and powerful as many applications need. This is by design and is not bad news at all. ASP.NET built-in controls supply a wealth of low-level functions, plus some aggregation mechanisms to combine them together into sophisticated controls. Complex and rich controls are usually not general-purpose enough to fit well into a system framework; in other cases, just the extreme specialization makes these controls hardly configurable beyond the threshold set by the author. In the end, they are either useful or notno middle courses. In light of this, the design of the .NET Framework sounds particularly reasonable, but it leads straight to the conclusion that programmers have to build their own highly specialized controls. When it comes to this, state maintainance is often the most requested feature. Lets review the options you have to create stateful custom web controls.
You can store any state needed by a control in one of the intrinsic objects living on the server (e.g., Session, Cache). Alternatively, you can use a client-side storage mechanism such as hidden fields or cookies.
You can use the Session object as long as your control and the hosting application is configured for that. The value of the EnableSession property for the page plays a critical role and determines what the code can do with the session state. Session state can be disabled altogether, used in a read-only way, or accessed in read/write mode.
If you store your custom data to the Session object, you must pay attention to the name you choose for each of the needed slots. The Session object is a unique shared data container for all controls in all pages in the same session. If more instances of a control are available in the same session, they would override each others settings unless appropriate countermeasures are taken. It is necessary for you to use a naming convention that makes a certain value unique to each control instance. For example, you could prefix each attribute with the controls ID.
Another point is that you cant make assumptions about the type of storage set for the session state. For example, if you happen to use a DataSet over remote storages like SQL Server, you may slow down your application due to the extra serialization required to move the bytes. As a control author, you do not set the session state mode. Finally, note that using session state places data in the web servers memory, which may be a problem in the long run. If you do that, at a minimum, you should document it very well.
An alternative approach entails using the Cache object, which a few ASP.NET 2.0 built-in controls do. However, in this case you are responsible for the uniqueness of the slot names also across multiple sessions. (The Cache object, in fact, is global to all sessions.)
Sometimes your state can be stored in the ViewState collection and sent back and forth between the client and the server. However, be aware that also in this case, the view state can be disabled by the page or the application, thus potentially breaking your code.
Summarizing, best practices seem to be the following:
- Use Cache with a proper naming convention (decided by you), and take into account the unfortunate scenario in which your cached items are emptied or invalidated.
- Build your own viewstate mechanism based on hidden fields. You collect data in a name/value collection. Then, you serialize it to a hidden field in PreRender and deserialize it in b.
Dino Esposito is Wintellect's ADO.NET and XML expert, and a trainer and consultant
based in Rome, Italy. Dino is a contributing editor to Windows Developer
Network and MSDN Magazine, and the author of several books for Microsoft
Press including Building Web Solutions with ASP.NET and ADO.NET
and Applied XML Programming for .NET. Contact Dino at [email protected].