Nov 16 2009

Got ViewState?

Category: .NET | ASP.NET | Best Practices | Tips & TricksDavid @ 10:58

A few months ago I wrote a couple of posts on Managing Session Variables in ASP.NET using a Proxy. Since then I have thought about the need to write a post addressing the use of the ViewState as well.  As with SessionState,  ViewState is essential just a Dictionary of String, Object pairs.  This means that at design time you have to do a fair amount of type casting to use the objects you store in ViewState in a strongly typed manner.  It also introduces many of the same issues as using the native SessionState, such as:

  • the inability to know where you are using a given ViewState variable in your code.
  • the potential for mistyping a ViewState key when putting an object in ViewState or retrieving.
  • the increase in code to check for null values returned from ViewState.

Each of these issues is a pain to deal with on their own, but when the issues are compounded over a complex page then it really can make for a bad experience when developing.  The solution to this problem that I propose is to use custom properties on the page to access the various objects that are stored in ViewState.  Below is an example of a code behind page that illustrates how to do this.  This example assumes you have a class Person that defines properties of FirstName, LastName and ID, as well as a web page with two textboxes and a button.

   1: Partial Public Class _Default
   2:    Inherits System.Web.UI.Page
   3:  
   4:  
   5: #Region " Fields "
   6:  
   7:    Private Const _personViewState As String = "MyPerson"
   8:    Public Const QueryStringParameterPersonID As String = "pid"
   9:  
  10: #End Region
  11:  
  12: #Region " Properties "
  13:  
  14:    Public Property Person() As Person
  15:       Get
  16:          If ViewState(_personViewState) Is Nothing Then ViewState(_personViewState) = New Person
  17:          Return CType(ViewState(_personViewState), Person)
  18:       End Get
  19:       Set(ByVal value As Person)
  20:          ViewState(_personViewState) = value
  21:       End Set
  22:    End Property
  23:  
  24: #End Region
  25:  
  26: #Region " Methods "
  27:  
  28:    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  29:       If Not String.IsNullOrEmpty(Page.Request.QueryString(QueryStringParameterPersonID)) Then
  30:          'Get your user from your datastore and populate the Person Property with the returned user.
  31:          Person = PersonDAO.GetPersonByID(CInt(Page.Request.QueryString(QueryStringParameterPersonID)))
  32:       End If
  33:  
  34:       FirstNameTextbox.Text = Person.FirstName
  35:       LastNameTextBox.Text = Person.LastName
  36:  
  37:    End Sub
  38:  
  39:    Protected Sub SaveButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles SaveButton.Click
  40:       Person.FirstName = FirstNameTextbox.Text.Trim
  41:       Person.LastName = LastNameTextBox.Text.Trim
  42:  
  43:       'Persist your Person to your datastore, etc.
  44:    End Sub
  45:  
  46: #End Region
  47:  
  48: End Class

In this example you can see how I have abstracted the access to my ViewState Person object into a property that always returns an instance of a Person. You can of course have this property return null (Nothing) if you need or prefer that for your own development.  Either way you are still eliminating the direct reference to the ViewState allowing you to program against a strongly typed object.  As I did in my SessionProxy posts, I am using a private constant to hold the string value of my key to eliminate the chance of mistyping this value when using it in multiple places.

Another technique that I would like to point out in this post is the use of public constants to represent the string value of the query parameter names for this page.  By exposing a constant representing this value I then make it possible for other developers to easily see the parameters that my page accepts.  If they utilize the constant it will also allow me to change the actual string value of my parameter name at any point in time without affecting the functionality of my page. (I realize this is a big “If” that is reliant on team standards.)

Tags: , , , , ,

Comments are closed