Wednesday, January 29, 2014

How to leverage HttpContext.Current.Items

Inside ASP.NET we have access to HttpContext.Current.Items, a dictionary that lives during an HTTP request. I use it to store data that i process once, and use many times, during a request.

For example, I create objects based on the URL structure. If I can be sure that these objects are unique during a request, then it is safe to put them in HttpContext.Current.Items and just retrieve from there whenever I need them.
public class QueryStringHelper
{
  private static readonly CriteriaKey = "CRITERIA_KEY";

  public static Criteria GetCurrentCriteria()
  {
    if (HttpContext.Current.Items.ContainsKey(CriteriaKey))
    {
      return (Criteria )HttpContext.Current.Items[CriteriaKey];
    }             
    Criteria  criteria = ParseCriteria ( Request.Url.Query);
    HttpContext.Current.Items[CriteriaKey] = criteria;
    return criteria;
  }
}

Accessing Items dictionary inside a thread, different from the request thread
I use Tasks to to create separate threads that make requests to an external API. 
var task = Task.Factory.StartNew(api.Run);

Now inside the thread running api.Run I don't have access to HttpContext.Current.Items, because it is only available on the request thread.  Therefore,  when I call QueryStringHelper.GetCurrentCriteria() inside thread running api.Run, Items dictionary will be null and I will get Null Reference.

What we can do here is to get the criteria object reference and set it to a variable where it is accessible from inside the newly created thread.

api.Criteria = QueryStringHelper.GetCurrentCriteria();
var task = Task.Factory.StartNew(api.Run);