Click here to Skip to main content
14,972,707 members
Articles / Web Development / ASP.NET
Article
Posted 22 Jun 2011

Stats

20.8K views
3 bookmarked

Using Session State to Share Data between pages

Rate me:
Please Sign up or sign in to vote.
1.00/5 (3 votes)
22 Jun 2011CPOL5 min read
How to use the Session collection, avoiding common pitfalls

Introduction

This article explores how to use the Session collection, avoiding common pitfalls.

Background

The Session object is a convenient way to store information to be accessed by several pages. Given the order in which Asp.net events are executed it is necessary to follow some guidelines to avoid headaches when implementing this tecnique.

The session object presents some advantages which make it ideal for storing complex data:

  • It is easy to save and retrieve complex data
  • No data does not travel between the browser and the server

In spite of these advantages , some care must be taken , because session objects remain in memory as long as the session remains active . If many large objects are created they can chew up the servers memory quite rapidly. To circumvent this problem the following can be done .
Use session objects only for small objects.

  • Reduce the session timeout to a reasonable time ( e.g 20 minutes )
  • Add a logout button which calls Session.Abandon() method to terminate the session. 
  • If many objects are going to be stored use the sessionState mode=SQLServer. This will reduce the performance, but will preserve the server’s memory. 

Using the Code

For the purpose of this article , we will use a very simple compound object : an Order which is composed of a header and a detail. 

C#
 public class OrderItem {
  private string _article;
  private Decimal _quantity;

  public String Article {
    get { return _article; }
    set { _article = value; }
  }
  public Decimal Quantity {
    get { return _quantity; }
    set { _quantity = value; }
  }
 
}

public class Order
{
  private DateTime _createdOn;
  private string _title;
  private List<OrderItem> _items;

  public DateTime CreatedOn {
    get { return _createdOn; }
  }
  public string Title {
    get { return _title; }
    set { _title = value; }
  }

  public List<OrderItem> Items {
    get { return _items; }
  }

  public Order(){
    _createdOn = DateTime.Now;
    _items = new List<OrderItem>();
  }
} 

Application Structure

We will use the Default page to edit the header ( title and CreatedOn properties ) and a Detail page for the details list ( article , quantity ) .

The key factor when using this technique is to have clear that the page_load event occurs before any of the control events. Hence , most of the Session handling will be done within this event.

The Root Page

The root page is the page where the topmost data of the object is edited. The form layout is very simple, it consists of two fields: title and createdOn. The createdOn field is read only. It also has two buttons : Clear, which clears the title and Details which navigates to the detail form.

RootPage.png

First we will define some helper methods to store and retrieve the Order object. These methods use the session object and a public order member.

C#
public Order order;

protected void setOrder() {
  Session["Object"] = order;
}

protected Order getOrder() {
  return (Order)Session["Object"];
}
We now need a way to know if the page is being loaded for the first time or as a result of coming back from the detail page. We will use another session object for this purpose:
C#
protected string getFromPage() {

  string result = (string)Session["FromPage"];
  if (result == null) {
    return "";
  } else {
    return result;
  }
}

Finally we need to handle the creation, storage and retrieval of the Order object. We have three cases:

The first case occurs when the application is starting and the Default page is being loaded for the first time. In this case we need to create the object and store it in the Session :

C#
if (!this.IsPostBack) {
  if (getFromPage() == "") {
  // Create the object and Save it in the Session
    order = new Order();
    setOrder();
  }       

Next , we need to handle the case in which we are returning from the detail page . In this case we only need to retrieve the object from the Session.

C#
else {
  order = getOrder();
}

Finally , we need to handle postbacks. When a page is re-loaded , the page is actually re-created using the viewstate information. Since our Order object is not part of the viewstate , it will be destroyed ( or more accurately the pointer will be set to null ), therefore we must retrieve it from the session state :

C#
} else {
    order = getOrder();
}

Now we need two more helper methods that allow us to move the data from the form into the object and vice versa. The methods are very simple because we only have two properties and one of the properties is read-only ( CreatedOn ).

C#
protected void fillForm() {
    this.txtTitle.Text = order.Title;
    this.txtCreatedOn.Text = order.CreatedOn.ToString();
  }
  
  protected void fillObject() {
    order.Title = txtTitle.Text;   
  }

The code for the button handlers is straightforward. The detail button simply redirects the user to the detail page. The clear button clears the title in the object and updates the form ( this could be done exactly in the other way (clear the control and update the object ).

C#
protected void btnNextPage_Click(object sender, EventArgs e) {
  fillObject();
  Response.Redirect("~/Detail.aspx");
}

protected void btnClear_Click(object sender, EventArgs e) {
  order.Title = "";
  fillForm();
}  <span class="Apple-style-span" style="color: rgb(255, 153, 0); font-family: Verdana, Arial, sans-serif; font-size: 13px; font-weight: bold; line-height: 16px; white-space: normal; "> </span>

The Detail Page 

The details form is made of a gridView in which we can view the order items and a couple of fields to add new details to the Order and two buttons: one to add the items and another to navigate back to the root page ( default.aspx) 

DetailPage.png

In the detail form we need two helper methods: one to get the order object and another to set the source page :

C#
protected void getOrder() {
  order = (Order)Session["Object"];
}

protected void setPage(){
  Session["FromPage"] = Page.Form.ID;
}

Since this is a detail screen , the code for the page_load event is a lot simpler. We always read the Order object when the event is executed ( because when this screen is reached , the root page has already created the Order object).

C#
protected void Page_Load(object sender, EventArgs e){
  //The object is allways read from the Session
  getOrder();
  if (this.IsPostBack == false) {
    gvItems.DataSource = order.Items;
    gvItems.DataBind();
  }
}

Now we add the code for the “Add” button : We create an order item object , we fill it with the data from the form , we add it to the Items list in the order object and we update the GridView control.

C#
protected void btnAdd_Click(object sender, EventArgs e) {
  Decimal qty;

  OrderItem item = new OrderItem();
  item.Article = txtArticle.Text;
  Decimal.TryParse(txtQuantity.Text,out qty);
  item.Quantity = qty;
  order.Items.Add(item);
  gvItems.DataSource = order.Items;
  gvItems.DataBind();

}

The last task is to create the handler for the “back” button. We need to call the setPage() method so that the root page (default.aspx) knows it is being loaded as a result of returning from the Detail page, we then redirect the application to the root page.

C#
protected void btnBack_Click(object sender, EventArgs e) {
   setPage();
   Response.Redirect("~/Default.aspx");
 }

Points of Interest

  Information can be passed between pages easily using the Session state. The order of events must be considered when using this technic to avoid getting a null object. The lifetime of the Session must be tunned if a large number of users is expected. This is a good technic to implement a shopping cart and small but complex objects. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Armando de la Torre
Software Developer (Senior) Self-employed
Mexico Mexico
Senior SAP Consultant ( ABAP / MM / Workflow ).
Delphi Developer
C# Asp Developer

Comments and Discussions

 
QuestionWhat happens Pin
HaBiX24-Jan-14 3:53
MemberHaBiX24-Jan-14 3:53 
when you have multiple browsers open and they all get same session?
GeneralMy vote of 1 Pin
mhamad zarif23-Jun-11 2:19
Membermhamad zarif23-Jun-11 2:19 
Question[My vote of 1] It's hard to find a start point to where your code is very bad... Pin
Seishin#22-Jun-11 20:52
MemberSeishin#22-Jun-11 20:52 
AnswerRe: [My vote of 1] It's hard to find a start point to where your code is very bad... [modified] Pin
JV999922-Jun-11 21:12
professionalJV999922-Jun-11 21:12 
AnswerRe: [My vote of 1] It's hard to find a start point to where your code is very bad... Pin
Armando de la Torre23-Jun-11 12:06
MemberArmando de la Torre23-Jun-11 12:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.