How To: Create a Strongly-Typed Property For HttpContext.Items

HttpContext.Items is one of my favorite properties in ASP.NET.  If I want to communicate a value from the HTTP pipeline to a page and then to a user control, this is my method for doing so.  Because the Items property is an implementation of IDictionary, the key/value pair is not strongly-typed.  If I am going to access a value often, I would like to make the call as simple as possible.  Here is an example of a property I created that "wraps" HttpContext.Items around a key value, yet exposing the value as a string, not object:

const string KEY_ERROR_MESSAGE = "key:errormessage";
public static string ErrorMessage
{
    get { return HttpContext.Current.Items[KEY_ERROR_MESSAGE] as string; }// get
    set { HttpContext.Current.Items[KEY_ERROR_MESSAGE] = value; }// set
}// property

9 Comments

  • I never understood this " as string" thing. You fully expect it to be a string, and if it's not a string what then? You ignore it? That seems totally wrong to me. If you've defined as part of the contract that bucket this contains strings, then it sure as hell better have a string in it otherwise something is wrong. If it doesn't have a string, you WANT it to fail so you can go in there, find out why, and FIX it.

    What I'm saying is that you should use (string)HttpContext.Current.Items[KEY_ERROR_MESSAGE] instead of (HttpContext.Current.Items[KEY_ERROR_MESSAGE]as string).

    If you actually had a temporary value, and checked it for null, and then did something with it, well that's a different story. But you aren't. Cast it properly!

    Please help stop this terrible meme!!

  • Yes, this is much better than just a plain text, but I learned to rely on enumerations rather than strings or constants. So, HttpContext.Current.Items[ItemKey.ErrorMessage] would be my way of doing it.

    A different question would be how you are wrapping the HttpContext.Current.Items and not use it directly? NUnit testing, mocking - I find it difficult to implement if you use session/cache/items directly...

  • When I need context items, I build a class with a static GetCurrent() or Current depending on how I will use it.

    public class ContextInfo
    {
    private static string contextKey = typeof(ContextInfo).FullName;
    private ContextInfo()
    { }
    public static ContextInfo GetCurrent()
    {
    ContextInfo contextItem = HttpContext.Current.Items[contextKey] as ContextInfo;
    if (contextItem == null)
    {
    contextItem = new ContextInfo();
    HttpContext.Current.Items[contextKey] = contextItem;
    }
    return contextItem;
    }
    private string _errorMessage;

    public string ErrorMessage
    {
    get { return _errorMessage; }
    set { _errorMessage = value; }
    }


    }

  • Nice tips. I never thought of passing values like this. Thanks

  • How do you keep the keys straight across pages and user controls?

  • Joe: Its only saved in the context of the current request.

  • You should probably snag a local reference to the current context as a member variable as well rather than doing an HttpContext.Current lookup each time a property is called.

  • Jayson,

    Your suggestion to put the value in a local reference appears good - until you consider concurrent users. Placing a value in a local static variable will render havoc when 10 users are calling the same static method. The benefit to my code sample is that it honors each unique call to the method by returning the appropriate value fot that specific HTTP context.

  • Several comments were given regarding "soft cast"

    Consider the intent behind this property. It is there to mask the details of HttpContext.Current.Items. Thus, when this property is used in the respective web-site, developers will not have *any choice* but to populate the property with a string. The "set" in this property is expecting "value" to be nothing other than a string. Thus (and why the blog post has strongly-typed in title), there will be a compiler error if any developer tries to use it incorrectly. I would prefer compiler error over runtime exception any day.

Comments have been disabled for this content.