State management with Context.Items in ASP.NET

Passing variables between pages is a task that is sure to arise in every ASP.NET web application. ASP.NET provides many options for state management including session variables, cookies, the QueryString, etc. Each of these have their strengths and weaknesses and each is designed for different circumstances, it just depends on your requirements. This guide will focus on the use of the Context.Items collection to pass variables between pages.

Say I have a paged named "ProductListing" the contains a list of products. When I click on one of the products, I want to redirect the user to a page named "ShowProduct". How do I tell "ShowProduct" which product to show?

One possible approach is to pass the product Id through the QueryString, then redirect to the "ShowProduct" page as shown in listings 1 and 2.

Me.Response.Redirect("ShowProduct.aspx?Id=4")
Listing 1: "ProductListing" using the QueryString
Dim ProductToShow As Integer = Me.Request.QueryString.Item("Id")
Listing 2: "ShowProduct" using the QueryString

The above approach is totally acceptable and will certainly work. There are however several disadvantages, some of which are listed below.

A better approach is to store the product Id in the Context.Items collection, then use Server.Transfer to redirect to the "ShowProduct" page as shown in listings 3 and 4.

Me.Context.Items.Add("Id", 4)
Me.Server.Transfer("ShowProduct.aspx")
Listing 3: "ProductListing" using the Context.Items collection
Dim ProductToShow As Integer = Me.Context.Items.item("Id")
Listing 4: "ShowProduct" using the Context.Items collection

Server.Transfer performs a server-side redirect that is transparent to the user, meaning there is no need of a round trip. The Context.Items collection is also capable of storing objects instead of just plain character data.

It is important to keep in mind that values stored in the Context.Items collection only last for the current request. If I were to do a postback on the "ShowProduct" page, the Context item "Id" would be lost. Most of the time this is convienient since we only need to store that value between pages and no longer.

What if I wanted to add a button named "MoreInfo" that expands the information shown on the "ShowProduct" page? This would cause a postback to the "ShowProduct" page and the product Id would be lost. So now the question is, how do I preserve the product Id on the current page?

The solution is to store the product Id in the ViewState collection. Then, every time the page is requested, the product Id will be delivered with the page to the client. If the page happens to postback again, we simply pick up the product Id from the ViewState collection.

Dim ProductToShow As Integer

If Not Me.IsPostBack Then
    ProductToShow = Me.Context.Items.Item("Id")
    Me.ViewState.Add("Id", ProductToShow)
Else
    ProductToShow = Me.ViewState.Item("Id")
End If
Listing 5: Preserve values with the ViewState
Related Links