.net cookies, do I have to send to browser? - asp.net

After I create or modify a httpcookie, do I have to do add it to the response.cookies collection? (if yes, only if its a new cookie or even if I am modifying one)

If you don't add a cookie to the Response.Cookies collection, it will never be sent to the browser. However, once you add the cookie to the collection, you can modify it as you please and the last value you set is what will be sent to the browser. What you are adding to the collection is a reference to your HttpCookie object, and the cookie is not sent to the browser until the end of the request life cycle.

If it is new it needs to be added to the Response.Cookies collection to be stored, but you can access the collection like an array.
Response.Cookies["foo"] = myCookie;
This will take care of the adding for you. FYI, if the cookies has not been created the value will return null.
However the cookie will be updated if you refer to the collection like this:
HttpCookie myCookie = Response.Cookies["foo"];
Any modifications to myCookie will be made to the cookie in the collection because in C# when you assign a variable to an existing class object, that object is handled by reference and it is modified.

Related

Changing a cookie doesn't affect it until the next Request - how to fix this?

I am familiar with Microsoft's "best practices" for handling the life-cycle of a cookie (as defined on MSDN), and am following these, but have found an odd scenario that I need to fix. I can't imagine I'm the first to experience this, so wanted to see what the community's take on this was.
By the way, one obvious fix for what I am about to describe would be to force a re-direct, but for reasons I won't go into, a 302 is not an option.
Okay, so I receive a WebRequest and in that I have a specific cookie. Depending on the flow, I need to "remove" this cookie. To do this, I set the Response Cookie's value to null and set its expiration date to sometime last year.
However, later on, a very separate part of the code attempts to re-read the cookie and - guess what - it finds the old value. Note: this is still part of the SAME web-request, we've not yet returned to the client.
When we return to the Client's browser, the cookie is duly removed.
One solution I have is that, at the very beginning of the web-request, I copy the Request cookies into a separate NameValueCollection.
Every time I update a cookie value, I update both the cookie in the Response.Cookies collection, and I update the value in my separate NameValueCollection.
Everytime I delete a cookie, I expire the cookie in the Response.Cookies collection, and I remove it from the NameValueCollection
Every time I add a new cookie, I add it to both the Response.Cookies collection and my NameValueCollection.
Whenever I want to read a cookie's value, I read it from my NameValueCollection.
Thoughts?
Thanks
Griff
I first check if the Resonse.Cookies.AnyKeys contains my Cookie Name. If it does, then I read from the Response cookies. If it doesn't then I read from the Request cookies.

MVC Cookie losing values after a HTTP Request & Cookie Add value

I have a multi key-value pair cookie. The cookie is a session cookie, i.e. not persistent. It contains several key-value pairs of data and well within the 4k size limit.
What's working: In my initialise action method (on Controller A), the cookie has a number of key-value pairs successfully added to it. All good so far.
Problem: When I navigate to another page, i.e. different action method (on Controller B), and then add a value to the cookie, I find all the previous values in the Cookie are now gone.
Please note, I verified the problem occurs only when a new value is added here. NOT adding a value to the cookie and navigating across many pages (and controllers) the existing values in the cookie are all preserved.
Investigations: I have spent one and a half days on this and tried a number of thing. In my cookie WriteCookie() method:
Making the Cookie persistent (by setting it's expiry to tomorrow). Verified the cookie in Firefox exists and has the correct date. But once I add a value to the cookie in Controller B, the cookie has lost all it's data.
Create a new cookie with the same name, added the previous values to this new cookie along with the new value. But again, navigating to another page (Controller B) and adding a value to the cookie has lost all it's previous data.
Code: Below is the original code I started with which doesn't contain the many heartbreaking attempts:
public static class CookieHelper
{
public static string ReadCookie(string key)
{
string value = string.Empty;
HttpCookie cookie = HttpContext.Current.Request.Cookies["mycookie"];
if (cookie != null)
{
value = HttpContext.Current.Request.Cookies["mycookie"].Values[key];
}
return value;
}
public static void WriteCookie(string key, string value)
{
HttpContext.Current.Response.Cookies["mycookie"].Values[key] = value;
}
}
Can anyone please help and explain why the cookie values are being lost. My guess, for some unknown reason subsequent writes to the cookie AFTER a HTTP Request is creating a new cookie and overwriting the existing cookie.
From MSDN:
You cannot directly modify a cookie. Instead, changing a cookie consists of creating a new cookie with new values and then sending the cookie to the browser to overwrite the old version on the client.
Modifying an individual subkey is the same as creating it.
To delete an individual subkey, you manipulate the cookie's Values collection, which holds the subkeys. You first recreate the cookie by getting it from the Cookies object. You can then call the Remove method of the Values collection, passing to the Remove method the name of the subkey to delete. You then add the cookie to the Cookies collection so it will be sent in its modified form back to the browser.

session.abandon is not generating new session

I am using asp.net 3.5
Session.Abandon() is not using the new SessionId.
Session["abc"] = "abc";
Session.Abandon(); //Session id is same as checked in add watch
Yes, and this is by design. It will reuse the same session ID.
See http://support.microsoft.com/kb/899918
Also
http://weblogs.asp.net/karan/archive/2010/04/26/asp-net-session-state-revisited.aspx
You can Session.IsNewSession to identify wether the sesiion is new one or not instead of using the SessionId, ASP.net reuses SessionId, as suggested in the KB Article you can get around this by programmatic-ally setting the SessionId to null in the client side cookies.
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
Response.Redirect(Request.Path);
Session.Clear() then the session variables clear up but the user remaining in the same session (if you don't want him to relogin for example) and reset all his session specific data.
Session.Abandon() only takes effect after page is completely executed. So the current page that called Abandon still has that same session. All next browser calls will be on a new Session.i.e You lose that specific session and the user will get a new session key.

Why does HttpContext.Response.Cookies["foo"] add a cookie?

I have just spent half a day tracking down a bug due to the following behaviour: -
Imagine that there is not a cookie called "foo" in either the Http request's or response's cookie collections. The following code returns null
A) HttpContext.Current.Request.Cookies["foo"]
The following code creates a new cookie called "foo" (with path="/" and blank value), adds it to the response's cookie collection and returns that
B) HttpContext.Current.Response.Cookies["foo"]
So (B) has the side effect that any pre-existing cookie called "foo" is overwritten on the client's browser.
This is not a bug. Someone actually coded this deliberately. Here is the disassembly of the Get method (the Item[string name] indexer delegates to this method.
public HttpCookie Get(String name) {
HttpCookie cookie = (HttpCookie)BaseGet(name);
if (cookie == null && _response != null) {
// response cookies are created on demand
cookie = new HttpCookie(name);
AddCookie(cookie, true);
_response.OnCookieAdd(cookie);
}
return cookie;
}
Obviously the MSDN docs do not mention this behaviour (although some users have added comments at the bottom of the docs that describe this behaviour).
My question is can someone explain to me the rational why the HttpCookieCollection class has this behaviour.
From MSDN doc about HttpCookieCollection.Get method: http://msdn.microsoft.com/en-us/library/ezy11xy2.aspx
If the named cookie does not exist, this method creates a new cookie
with that name.
So yes, this is done on purpose.
Why? At a guess because it makes sense. If you're doing anything with the response the typical use case is that you want things to be sent to the browser.
You check for values inbound (Request.Cookies) and then you set them outbound (Response.Cookies). The Request is a READ, the Response is a WRITE.

HttpCookieCollection.Add vs HttpCookieCollection.Set - Does the Request.Cookies collection get copied to the Response.Cookies collection?

I just want to clear this up.
I know that if I have set a cookie on a previous request, it will show up in my Request.Cookies collection.
I want to update my existing Cookie.
Are the cookies from my Request.Cookies collection already copied to my Response.Cookies collection? Do I need to add a new cookie with the same key using Response.Cookies.Add(), or do I need to use Response.Cookies.Set()?
There is a difference:
Response.Cookies.Add() will allow duplicate cookies to be set http://msdn.microsoft.com/en-us/library/system.web.httpcookiecollection.add.aspx
Response.Cookies.Set() will make sure the cookie is unique by first checking to ensure the cookie doesn't exist http://msdn.microsoft.com/en-us/library/system.web.httpcookiecollection.set.aspx
Duplicate cookies typically requires extra handling to determine which is the most recent. I'm not sure of a case when you would want duplicate cookies on the same site, maybe someone else can chime in with an example
Edit: In your case, you want to use set because you are updating.

Resources