views:

118

answers:

3

Anyone know how I can convert Request.Cookies into a List<HttpCookie>? The following didn't work as it throws an exception.

List<HttpCookie> lstCookies = new List<HttpCookie>(
    Request.Cookies.Cast<HttpCookie>());

Exception: Unable to cast object of type 'System.String' to type 'System.Web.HttpCookie'

+2  A: 

.Cookies.Cast<HttpCookie>(); tries to cast the collection of keys to a collection of cookies. So it's normal that you get an error :)

It's a name -> value collection, so casting to a list wouldn't be good.

I would try converting it to a dictionary.

For example:

Since Cookies inherits from NameObjectCollectionBase you can GetAllKeys(), and use that list to get all the values and put them in a Dictionary.

For example:

Dictionary cookieCollection = new Dictionary<string, object>();

foreach(var key in Request.Cookies.GetAllKeys())
{
    cookieCollection.Add(key, Request.Cookies.Item[key]);
}
Snake
+2  A: 

The reason this happens is because the NameObjectCollectionBase type that Request.Cookies derives from enumerates over the keys of the collection and not over the values. So when you enumerate over the Request.Cookies collection you are getting the keys:

public virtual IEnumerator GetEnumerator()
{
    return new NameObjectKeysEnumerator(this);
}

This means that the following will work:

string[] keys = Request.Cookies.Cast<string>().ToArray();

I guess you could try the following which might be considered ugly but will work:

List<HttpCookie> lstCookies = Request.Cookies.Keys.Cast<string>()
    .Select(x => Request.Cookies[x]).ToList();

UPDATE:

As pointed out by @Jon Benedicto in the comments section and in his answer using the AllKeys property is more optimal as it saves a cast:

List<HttpCookie> lstCookies = Request.Cookies.AllKeys
    .Select(x => Request.Cookies[x]).ToList();
Darin Dimitrov
But then you lose the key -> value connection :)
Snake
@Snake, I agree with you that this is not optimal from performance standpoint as it will enumerate the collection multiple times but if you have a couple of elements it might not be dramatical.
Darin Dimitrov
Using the AllKeys member of HttpCookieCollection saves a cast. See my answer for code.
Jon Benedicto
@Jon, good point.
Darin Dimitrov
+1  A: 

If you really want a straight List<HttpCookie> with no key->value connection, then you can use Select in LINQ to do it:

var cookies = Request.Cookies.AllKeys.Select(x => Request.Cookies[x]).ToList();
Jon Benedicto