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

Published Thursday, July 12, 2007 11:59 PM by Palermo4
Filed under: , , ,

Comments

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

Friday, July 13, 2007 10:47 AM by Joe

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!!

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

Friday, July 13, 2007 10:50 AM by Sean

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...

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

Friday, July 13, 2007 4:33 PM by AndrewSeven

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; }

}

}

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

Friday, July 13, 2007 9:36 PM by Justin

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

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

Friday, July 13, 2007 10:21 PM by karl

ok solution for 1 values, but create a custom context class is a much better idea:

codebetter.com/.../Give-your-website-more-context.aspx

curious, why use a soft cast? don't you WANT an exception to happen if someone's trying to store something else in there? I mean, better to know that you have something un-castable to a string in there than ignoring it.

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

Friday, July 13, 2007 10:40 PM by Joe

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

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

Saturday, July 14, 2007 10:13 AM by AndrewSeven

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

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

Saturday, July 14, 2007 6:19 PM by jayson knight

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.

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

Tuesday, July 17, 2007 2:13 AM by Palermo4

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.

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

Tuesday, July 17, 2007 2:24 AM by Palermo4

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.

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

Tuesday, July 17, 2007 2:29 AM by Palermo4

Sean,

I like your suggestion for using an enumeration for the key.  My only dislike for this is in code-generation scenarios.  It is easy for my to code-gen this property with corresponding constant (or literal text).  However, unless I know all my keys up front, I can not auto-gen my enumeration.  Especially if I have these spread about multiple physical files.  Unless there is such thing as partial enums....

Leave a Comment

(required) 
(required) 
(optional)
(required)