Inconvenient ASP.NET cookies


Recently I’ve been working on a SharePoint solution that was persisting some state information. Originally this solution was relying on Session State but because of some extra configuration complexity that using Session State with SharePoint requires we decided to replace the Session State with cookies. Although both approaches are not exactly the same they were both sufficient in the scope of the solution. And although you might expect no rocket science when working with ASP.NET cookies there are a few things that keeping in mind might save you some painful hours.

A bit of a background

The solution I was working on was using Session State to store some information. As you know storing information in Session State is pretty straight-forward:

HttpContext.Current.Session["myValue"] = "some value";

Retrieving information is comparably easy:

string myValue = HttpContext.Current.Session["myValue"] as string;

In order to check if a value has been set all you need to do is to check the value of the specific Session variable:

if (HttpContext.Current.Session["myValue"] != null)
{
    // session variable set
}
else
{
    // session variable not set
}

If the value is different than null the session variable has been set.

If your code relies on the Session State it is a good practice to check first if it’s been enabled. You can do this by checking if the Session object is not null:

bool sessionEnabled = HttpContext.Current.Session != null;

A non-null value means it’s been configured while a null means that there is no Session State available for your solution to use.

So what’s the big deal if you would like to use cookies instead?

ASP.NET cookies 101

First important difference is that there are request and response cookies and that they are not the same. Response cookies are cookies that you want the browser to set on the client machine. Request cookies are cookies that already exist on the client side and have been sent by the browser together with the request. In comparison there is only one Session State. and it lives on the server.

Comparably to when using Session State, when working with cookies you might want to check first if it’s available to your solution. In contrary to the Session State, cookies are handled on the client and it’s the browser that determines if the cookies are supported or not. You can check for the availability of cookies by querying the browser capabilities:

bool supportsCookies = HttpContext.Current.Request.Browser.Cookies;

Once you know that the client browser support cookies you can start using them in your code.

Working with cookies and data

When working with data at the first glance things look the same as you were using Session State. To set a value you create a new cookie object, you set a value and an expiration date and add the cookie to the response cookies:

HttpContext.Current.Response.Cookies.Add(new HttpCookie("myCookie")
{
    Expires = DateTime.Now.AddDays(7),
    Value = "myValue"
});

Retrieving the data is however a little trickier. In the easiest scenario you could use the following snippet:

HttpCookie myCookie = HttpContext.Current.Request.Cookies["myCookie"];
if (myCookie != null)
{
    // cookie has been set
}
else
{
    // cookie hasn't been set
}

If the cookie has been set on the client browser, the returned value will be other than null. If the cookie doesn’t exist on the browser, either because it hasn’t been set yet, it expired or has been removed by the user, the returned value will be null. There is however one more scenario worth paying attention to.

ASP.NET cookies “advanced”

When working with Session State the moment you set a session variable it becomes persisted and you can retrieve the value immediately in the same request/response. When working with cookies however, the cookie has to be persisted on the client first, meaning that in the straight-forward approach you would need another request to retrieve the value of a cookie set during the response.

One workaround for this behavior is checking for both request and response cookies, where the response cookie is leading:

HttpCookie responseCookie = HttpContext.Current.Response.Cookies["myCookie"];
HttpCookie requestCookie = HttpContext.Current.Request.Cookies["myCookie"];
if (responseCookie != null || requestCookie != null)
{
    // the cookie has been set
}

There is however one serious problem with the code above: it will always say that the cookie has been set!

One more thing about response cookies

There is one important difference between response and request cookies that you simply must know. If you ask for a request cookie that doesn’t exist, ASP.NET will return a null value – just as you would expect. However if you ask for a response cookie that doesn’t exist, ASP.NET will create a new cookie and return it just as if it has been set earlier during the response!

Looking back at the code snippet I’ve just showed you, you might realize by now that the first check will always result in true. So how to deal with it?

Instead of directly retrieving a response cookie, you should check first if it exists in the collection of response cookies or not. There are many ways of doing it, but probably the easiest one is to use the Contains extension method:

using System.Linq;

HttpCookie responseCookie = null;
if (HttpContext.Current.Response.Cookies.AllKeys.Contains("myCookie"))
{
    responseCookie = HttpContext.Current.Response.Cookies["myCookie"];
}

By checking if the response cookie exists first, you can ensure, that you will retrieve the cookie only if it’s been set earlier during the response, which will give you the expected result.

Having this in place you can provide experience comparable to when using Session State.

Summary

ASP.NET ships with Session State and cookies that both can be used for persisting state information. Although those mechanisms are not the same and each have some pros and cons there are scenarios when using both allow you to deliver comparable results. This is important especially when working with SharePoint, where using Session State requires you to do some extra configuration steps and using cookies instead might simplify your deployment process. Although working with ASP.NET cookies looks the same as working with Session State there are some subtle yet very important differences which if you don’t pay attention to may cause faulty behavior.

Technorati Tags: ASP.NET,SharePoint

Others found also helpful: