As Web applications are transmitted via HTTP, we have to carefully ensure that any state we require is kept between postbacks to the server. In ASP most state was handled by the Session State dictionary, but in ASP.NET controls intrinsically handled their own state via the viewstate mechanism. However, the problem with this is that viewstate can become large, especially when dealing with grids. One of the goals of ASP.NET 2.0 is to add flexibility by introducing three new state handling mechanisms:
As part of this support for session bases, state persistence is also supported. This allows state to be stored server-side when dealing with mobile browsers, where large pages can be a limiting factor for both memory and bandwidth reasons. Control StateIn ASP.NET 1.x, controls save state as part of the viewstate. However, viewstate is really intended to store state set by the application, not individual controls. Additionally, if viewstate is turned off at the page level, several controls break (e.g., the current view of a multiview or the sort order of a sortable data grid). The only solution is to reset the properties on every request, which is not always practical because the controls themselves decide what state they need. To solve this problem, a new state has been created, called control state, to store control-specific state. Control state is stored in a hidden field (called __CONTROLSTATE ) in the same way as viewstate, but it is completely separate from viewstate and thus works when viewstate is turned off. For example, consider a Pager control: <asp:Pager runat="server" /> This would normally require viewstate, but under the new model its viewstate is and the control state is 12 bytes. This can be found by looking at a new column when tracing is enabled, as shown in Figure 13.1. Figure 13.1. Page trace showing control state
Implementing Control State in Custom ControlsWhen creating custom controls, control state can be implemented by the following three steps:
Listing 13.14 shows an example. Listing 13.14 Implementing Control StatePublic Class MyControl Inherits WebControl Private _myProperty As Integer Protected Overrides Sub OnInit(E As EventArgs) Page.RegisterRequiresControlState(Me) MyBase.OnInit(E) End Sub Protected Overrides Function SaveControlState() As Object Return CType(_MyProperty, Object) End Function Protected Overrides Sub LoadControlState(State As Object) If State <> Nothing Then _myProperty = Convert.ToInt32(state) End If End Sub End Class It is important to remember that control state is designed for critical private storage of state, so storage should be kept to a minimum. Page State PersistenceASP.NET 1.x persisted all viewstate to a hidden control on a page. As mentioned earlier, this can be inconvenient for some devices (such as phones), where the reduced bandwidth means slower loading speeds and reduced memory means a limited page size. Under these circumstances it's sensible to store state on the server. In ASP.NET 2.0 the page adapter architecture allows for page state to be implemented by an object that inherits from a page state persister. This lets the page abstract the storage of state into a separate class, which the adapter can implement, allowing different state mechanisms to be implemented depending on the adapter. The framework supplies two page state persisters:
The latter of these is implemented in a way similar to the viewstate persistence in the MMIT from version 1.x. Session State PlugabilityBy default there are three ways to store session state:
These provide most users with what they need, but session state handling in version 1.x isn't extensible. ASP.NET 2.0 allows session state to be completely unplugged and replaced with a custom module. In addition, there is a new Session State ID module, allowing just the creation of IDs for session state to be replaced . Both of these allow custom data stores or even just custom handling of the session data. There are two ways to provide custom session state handling. The first is to author a completely new session state module; the other is to just replace portions of the existing system. The first of these is the most flexible solution but is the most complex, whereas the second is simpler because you can replace only those bits that need to be changed. For example, you could just implement an Oracle session provider. To replace the session state system, you can do any of the following:
Only the first of these is required to implement your own method of handling session state. Optionally you can implement your own HttpSession StateProvider to provide your own storage mechanism for session state or implement SessionIDModule to provide creation of session IDs. As mentioned, you don't need to implement thesethere's no requirement for a custom session state module to implement ID handling at all. In fact, you don't even need an HttpSessionStateProvider , although your custom class has to return an object that implements IHttpSessionState . Together the three of these provide a complete implementation of session state. The hierarchy of objects is shown in Figure 13.2. Figure 13.2. Session state object hierarchy
Once session state is implemented, you can simply replace the existing module with the new custom module by editing the httpModules configuration section (see Listing 13.15). Listing 13.15 Configuring Your Own Session State<configuration> <system.web> <httpModules> <remove name="Session" /> <add name="Session" type="AW.MyStateModule, MyStateModule" /> </httpModules> </system.web> </configuration> The second approach to customizing session state is to use the existing session state module but to replace portions of it, such as:
Only the session state store ( ISessionStateStore ) is required to customize session statereplacing other classes is optional, allowing the existing functionality to be preserved while customizing just selected sections. The hierarchy of these items is shown in Figure 13.3. Figure 13.3. Session state customization
If implementing a custom state provider class, this can be configured by modifying the sessionState section of the configuration file: <configuration> <system.web> <sessionState mode="Custom" customType="AW.MyStateModule, StateModule" /> </system.web> </configuration> A more detailed explanation of customizing session state is beyond the scope of this book. |