2

I am working on a class project and I've run into a problem I can't figure out. I have a feeling it's actually pretty easy, but I've been working on stuff so long I can't think straight anymore.

I have a login page that allows a user to login and pass 2 data items to the next page using Context.Items and Server.Transfer. Here is the code snippet:

Context.Items["preferred"] = true;
Context.Items["pageNum"] = 1;
Server.Transfer("ProductsShelf.aspx");

On the "ProductsShelf" page I can access those two items and use the data like so:

pageNumber = (int)Context.Items["pageNum"];

I am then using a switch-statement with pageNumber to display certain information:

switch (pageNumber)
{
    case 1:
        imgProd.ImageUrl = "assets/laptop.bmp";
        lbl_Name.Text = "Laptop";
        lbl_desc.Text = "This is a cheap laptop!";
        lbl_price.Text = "199.99";
        break;
}

Obviously there's other entries I'm omitting. What I want to do is click a next or previous button and use the event to change the Context.Items["pageNum"] data so the Page_Load() event uses different data in the switch-statement. Hope that makes sense. Here is one of the button click events:

protected void btn_Prev_Click(object sender, EventArgs e)
{
        if (pageNumber == 1 || pageNumber == 2)
        {
            Context.Items["pageNum"] = 1;
        }
        else if (pageNumber == 3)
        {
            Context.Items["pageNum"] = 2;
        }
        Context.Items["preferred"] = preferredCustomer;
        Server.Transfer("ProductsShelf.aspx");
}

The problem is that before the button click event fires, the form posts and clears the Context.Items and pageNumber values. This means that the button event if-statements never fire and it results in:

pageNumber = (int)Context.Items["pageNum"];

Being null, throwing an exception and making me very sad. So my question is, how can I go about retaining the values? Should I switch to Response.Redirect and have something like ?page=1 in the URL? Or will that clear too when the form posts? Hopefully I'm not doing this completely wrong.

If TL;DR, here's a quick summary:

  1. Context.Items has 2 values passed with Server.Transfer
  2. These values determine what's shown on the next page
  3. The form clears Context.Items and variables before button click event fires
  4. The values are null, the if-statement doesn't run, and the app throws an exception
  5. Question: how should I go about retaining those values?

Thanks a lot. :)

Sam
  • 317
  • 1
  • 4
  • 13

1 Answers1

3

HttpContext items can be used within one request only - it will be recreated for next request so your values are bound to lose. You should use view-state to preserve data across post-backs. In page load, you should check if data exists in context and then copy it to view-state. Then in button click events, you can read the data from view-state, put into the context items and do server.transfer. Here's simple sample code:

private int PageNumber
{
   get 
   { 
    var value = ViewState["pageNum"]; 
    return null == value? 1: (int)value;
   }
   set
   {
     ViewState["pageNum"] = value;
   }
}

private bool IsPreferredCustomer
{
   get 
   { 
    var value = ViewState["preferred"]; 
    return null == value? false: (bool)value;
   }
   set
   {
     ViewState["preferred"] = value;
   }
}

protected void Page_Load(object sender, EventArgs e)
{
    var preferred = Context.Items["preferred"];
    if (null != preferred)
    {
      IsPreferredCustomer =  (bool)preferred;
    }
    var pageNum = Context.Items["pageNum"];
    if (null != pageNum )
    {
      PageNumber =  (int)Context.Items["pageNum "];
    }
}

Use the same PageNumber property in event code.

VinayC
  • 47,395
  • 5
  • 59
  • 72
  • ok cool, I'll give this a try, but just out of curiosity because I've ran into this a couple times now, how are you expected to run button clicks and other various event driven functions when the form posts before it runs them? I mean what's the point of storing information in variables if you can't even use them? I feel like I need to implement some sort of AJAX style code so it runs it without actually refreshing the whole page. You get what I mean? – Sam Nov 04 '10 at 13:45
  • @perlox, variable would store info till their containing object (Page) lives. But page object gets destroyed when request ends. On postbacks, the object wold be re-created and view-state will be used to re-store control state. So, you need to use view-state, if information needs to be persisted over multiple requests. The same would apply in AJAX as well as because each AJAX request will be a different request. – VinayC Nov 04 '10 at 14:02
  • hmm, ok well I'll have to spend some time wrapping my head around this. Thanks for the responses! :) – Sam Nov 04 '10 at 14:08