Wednesday, January 26, 2011

Using HttpContext.Current.Items as a data storage for current HttpRequest

Did you ever use HttpContext.Current.Items?

Chances are there you didn't. Why? Because this is a least known thing which people talks about, but, this could be a good friend of you "in need". Let's see what this is and how this could be used effectively to carry out our works in better approach.

When an HttpRequest arrives at an application, the Request is processed and the result is usually served back to the browser (Or, client application) as HTML output. Since receives the Request, it goes though lots of steps. For example, it could go though the following steps:
  • Application_BeginRequest in Global.asax (If defined)
  • Init event in custom HttpModules (If defined)
  • Page_Load other life cycle events events in a Page
  • Page_Load other life cycle events events in a Master Page
  • Page_Load and other life cycle events in User controls
  • Method invocation on Dlls
While the Request is traversing through these steps, what if at step1 we have some data that we need to make available when the Request is traversing step2?

Lets see some examples where we may need to implement such requirement:


Suppose, we have an Application_BeginRequest() event handler at Global.asax which is executed for each Request, and, we retrieve some data from somewhere within this method:

void Application_BeginRequest(object sender, EventArgs e)
    //Retrieve some data from somewhere for each Request

Now, we need to make sure that this data is available to the target Page which will get executed, to avoid to load the same data again in the Page. How would we pass the data to the Page?


Suppose, we have a user control which retrieves data from the database using an expensive operation. Once the user control finishes executing, the data is to be served to another user control which does some other stuff with the same data. How could we pass the data from this user control to another user control?


Perhaps we have some data at the Page_Load event (Say, current user object), which we need to make available to each and every method that get executed on the Business and Data access layers and we don't really want to modify each and every method to accept a new parameter just because we need to make the data commonly available to all methods. What do we do?

I know, there are alternatives. We may use different approaches while we deal with each above examples. The easiest and most general approach which is being used in such cases is as follows:
  • Store the data in Session in Step1 
  • Retrieve the data from Session in Step2
  • Clear the data from Session in Step2 (Clear it because this Session data is not required for any other Request)
Unfortunately, the Session state is being misused in such approach. Session should be used to store data which are required for the current Session, not for the current Request, and hence, this is not obviously a best practice to use in such cases. Also, if someone forgets to clear the data from the Session at Step2, a BUG is given birth to the system.

Well, the good news is, HttpContext.Current.Items is the perfect solution for such scenario. This is a simple HashTable which lets you store and retrieve data as long as the HttpRequest is alive and traversing through different steps in its life cycle.

So, you could use HttpContext.Current.Items to store data in one step and retrieve later in other step as follows:

//Store data in Step1:
HttpContext.Current.Items.Add("Key", "Value");

//Retrieve data in Step2:
object value = HttpContext.Current.Items["Key"];

This HashTable could be considered as your Cache storage as long as the Request is being processed. This is a good friend indeed and be friend it with, and get benefited.

1 comment:

Post a Comment