Asp.net HttpCookie Read/Write problem - asp.net

I've been searching a solution for this problem but i couldn't have one. By the way i can't understand the reason of my problem.
The problem is:
My web application has a login page and gets logged user id from cookie. It worked before but 5-6 days ago because of something changed it didn't worked with IE. Now it doesn't work with any browser.
I can see the cookie in Chrome. When looked with Internet Explorer Developer Tool sometimes the cookie written but still can't read by IE
My web app is on Windows Server 2008 R2 BTW
Set my web.config:
<httpCookies domain=".domainname.com" httpOnlyCookies="false" requireSSL="false" />
Here is my SetCookie code
<!-- language: c# -->
string uId = "userID";
DateTime expireDate = DateTime.Now.AddDays(3);
HttpContext.Current.Response.Cookies["cookieName"]["uID"] = uId;
HttpCookie aCookie = new HttpCookie("cookieName");
aCookie.Values["uID"] = uId;
aCookie.Path = "/";
aCookie.Expires = expireDate;
aCookie.HttpOnly = false;
aCookie.Domain = "domainname.com";
aCookie.Name = "cookieName";
HttpContext.Current.Response.Cookies.Add(aCookie);
And this GetCookie code
<!-- language: c# -->
if (HttpContext.Current.Request.Cookies["cookieName"] != null)
{
System.Collections.Specialized.NameValueCollection UserInfoCookieCollection;
UserInfoCookieCollection = HttpContext.Current.Request.Cookies["cookieName"].Values;
userID = HttpContext.Current.Server.HtmlEncode(UserInfoCookieCollection["uID"]);
}
The scenario is:
trying to log in
SetCookie method triggered
End of SetCookie method there are two cookies "cookieName" and
"ASP.NET SessionId"
GetCookie method triggered
There is only "ASP.NET SessionId" and session value still same
Thanks for any help.

My problem solved. Changed my code to this
string uId = "userID";
DateTime expireDate = DateTime.Now.AddDays(3);
var httpCookie = HttpContext.Current.Response.Cookies["cookieName"];
if (httpCookie != null)
{
httpCookie["uID"] = uId;
HttpContext.Current.Response.Cookies.Add(httpCookie);
}
else
{
HttpCookie aCookie = new HttpCookie("cookieName");
aCookie.Values["uID"] = uId;
aCookie.Expires = expireDate;
HttpContext.Current.Response.Cookies.Add(aCookie);
}

This one had me stumped. But managed to solve it as follows. So basically setting the expiry as part of the initialiser does not work. Setting it after adding the cookie to the response object works!

Related

Retain the session value when browser is opened for the second time

First time login to the asp.net application,stored some session value
Eg: Session["Test"]="Saving Sesison";
Logout the application
When opened the browser for the second time,need to retain the same session value.
Eg: Session["Test"]="Saving Sesison";
How can i do that,can anyone help me with some solution to proceed further please.
if (!Page.IsPostBack)
{
if (Session["Test"] == null)
{
Binding data to repeater control(with out filter)
}
else
{
//Get Session value (To maintain session value across the browser)
var cookieSession = Request.Cookies["Test"]; //While opening the browser for the 2nd time,this line is getting null for all the browsers,but session is getting value for firefox & Chrome not for IE { Session["Test"] }
if (cookieSession != null &&!String.IsNullOrEmpty(cookieSession.Value))
{
Session["Test"] = cookieSession.Value;
}
Binding data to repeater control(with filter using session value)
}
}
//On Drop down selection.
protected void Dropdown_SelectedIndexChanged(object sender, EventArgs e)
{
Binding data to repeater control(based on the dropdown selected value)
Session["Test"] = Dropdown.SelectedItem.Text.ToString(); //To maintain the Dropdown selection all over the app
// Set it
if (Session["Test"] == null)
{
Session["Test"] = Guid.NewGuid().ToString();
var cookie = new HttpCookie("Test", (string)Session["Test"]);
Response.Cookies.Add(cookie);
}
}
ASP.NET Session scope is for only particular session only. So its not possible to have that kind of functionality.
But you can use Cache in same way and it will be there until you make it null or time period exceeds. But beware of fact that it will be there for every browser. So either you need to use different key(Unique key) not like 'test'
You have a few options. Though sessions should be sticky between a browser being re-launched assuming it's not in private/incognito mode. If you're finding the session is timing out too quickly you can extend it in Web.config
<system.web>
<sessionState timeout="10080" mode="InProc" />
</system.web>
Where timeout is in minutes. Note: If you're are debugging stopping and starting the debugger will reset your sessions. So will any kind of re-deployment of the application on IIS. If this is an issue for you, you should check out using something like the SQL session state provider: http://msdn.microsoft.com/en-us/library/vstudio/h6bb9cz9(v=vs.100).aspx
Another method of dealing with this is to store some kind of token in a cookie (again, only works if the browser is not in incognito/private mode, and the user data hasn't been flushed).
// Set it
if (Session["Test"] == null)
{
Session["Test"] = Guid.NewGuid().ToString();
var cookie = new HttpCookie("Test", (string)Session["Test"]);
Response.Cookies.Add(cookie);
}
// Get it
var cookieSession = Request.Cookies["Test"];
if (cookieSession != null && !String.IsNullOrEmpty(cookieSession.Value))
{
Session["Test"] = cookieSession.Value;
}
As a note using the SQL session state provider while is one of the more persistent storages there can be some serious overhead requirements. It's easy to rack up a couple of gigs worth of sessions that are being tracked.
In my experience a combination of cookies and the session provider seem to work best if you need to be very certain that some things are sticking to a users experience on the site.
Edit
So the issue with your drop down selection saver is it's always false and should never set the cookie.
protected void Dropdown_SelectedIndexChanged(object sender, EventArgs e)
{
//Binding data to repeater control(based on the dropdown selected value)
// add to Session
Session["Test"] = Dropdown.SelectedItem.Text.ToString();
// Add Cookie
var cookie = new HttpCookie("Test", (string)Session["Test"]);
Response.Cookies.Add(cookie);
}
Now to get your data back out, put this code in the actions/controllers to run BEFORE you try to access Session["Test"]
var cookieSession = Request.Cookies["Test"];
if (cookieSession != null && !String.IsNullOrEmpty(cookieSession.Value))
{
Session["Test"] = cookieSession.Value; // Should contain the selected text from the drop down
}

Clear multidimensional cookie in c#

I used multidimensional cookie to store a cookie in my application.
For example
HttpCookie MyCookie = Request.Cookies["Temp"] as HttpCookie;
if (MyCookie != null)
{
MyCookie.Values["SID"] = Session.SessionID;
MyCookie.Values["NAME"] = "NAME";
MyCookie.Values["abc"] = "abc";
MyCookie.Values["xyz"] = "xyz";
...
}
Now to retrieve this multidimensional cookie I used.
string s = Request.Cookies["Temp"]["SID"]
My question is I want to expire only "SID" value from the "Temp" cookie. I tried with this
Request.Cookies["Temp"]["SID"] = null;
but it's not working. What should I do clear particular index from multidimensional cookie?
This is already answered in the following question: ASP.NET Cookie Sub-Value Deletion
HttpCookie.Values is a NameValueCollection, so you can modify that collection - but you will need to re-send the cookie as a new one to overwrite the old one:
HttpCookie cookie = Request.Cookies["Temp"];
if(cookie != null)
{
cookie.Values.Remove("SID");
Response.AppendCookie(cookie);
}
This is also explained in the following MSDN page: http://msdn.microsoft.com/en-us/library/aa289495(v=vs.71).aspx#vbtchaspnetcookies101anchor9
This will do.
Request.Cookies["Temp"].Values["SID"] = null;
Hope it helps. :)

ASP.NET: 403 - Forbidden: Access is denied. You do not have permission to view this directory or page using the credentials that you supplied

When a valid user logs into the system and closes the browser without logging out, it occasionally (i.e. not immediately after but in the next day) prevents the user to login back into the system throwing the following:
Error: 403 - Forbidden: Access is denied. You do not have permission to view this directory or page using the credentials that you supplied.
This question refers to the same problem but in his solution, he decided not to use persistent cookies by passing false as a parameter when creating the FormsAuthenticationTicket, which is not the desired solution.
This is how I am creating the cookie:
private void createCookie(string username, int customerID, bool persist)
{
HttpCookie cookie = FormsAuthentication.GetAuthCookie(username, persist);
cookie.Expires = DateTime.Now.AddHours(12);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
var userData = customerID.ToString();
var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userData);
cookie.Value = FormsAuthentication.Encrypt(newTicket);
Response.Cookies.Add(cookie);
}
Any ideas on how to solve this?
When a valid user logs into the system and closes the browser without
logging out, it occasionally (i.e. not immediately after but in the
next day) prevents the user to login back into the system...
I could be dense but isn't the code working like the way you implemented it?
Namely, in createCookie(): you specify cookie.Expires = DateTime.Now.AddHours(12);, which marks the cookie to expire 12 hours after it is issued.
In Asp.net 1.0, if FormsAuthenticationTicket.IsPersistent is set, the ticket will automatically have a valid duration of 50 years from the time issued.
However in Asp.net 2.0 this is no longer the case. If FormsAuthenticationTicket.IsPersistent is set to false, the ticket will have a valid duration identical to the Session timeout period. If FormsAuthenticationTicket.IsPersistent is set to true, the valid duration will default to the Forms Authentication timeout attribute. You have the expiration time set to issue time plus 12 hours, so I would expect the ticket to stop working after 12 hours. Assuming you are using Asp.net 2.0+, hopefully this should explain the hehavior your are seeing. I would suggest try increasing the expiration time to a longer duration and see if the problem goes away.
There is no inherent problem with including your own userData in the auth cookie.
In one of our websites we use the asp.net login control, and add the following event listener with much success:
protected void Login1_LoggedIn(object sender, EventArgs e)
{
//... unimportant code left out
//Update the users ticket with custom userInfo object
string userData = userInfo.Id.ToString("N");
HttpCookie cookie = Response.Cookies.Get(FormsAuthentication.FormsCookieName);
FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(cookie.Value);
FormsAuthenticationTicket newTicket =
new FormsAuthenticationTicket(
oldTicket.Version,
oldTicket.Name,
oldTicket.IssueDate,
oldTicket.Expiration,
oldTicket.IsPersistent,
userData,
oldTicket.CookiePath);
cookie.Value = FormsAuthentication.Encrypt(newTicket);
}

cookie isn't updated until page refresh... how to avoid that?

I have some asp.net pages that read and write cookie values. During the life cycle of a page it may update the cookie value and then need to read it again further in the code. What I've found is that it's not getting the latest value of the cookie until a page refresh. Is there a way around this? Here's the code I'm using to set and get the values.
public static string GetValue(SessionKey sessionKey)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiePrefix];
if (cookie == null)
return string.Empty;
return cookie[sessionKey.SessionKeyName] ?? string.Empty;
}
public static void SetValue(SessionKey sessionKey, string sessionValue)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiePrefix];
if (cookie == null)
cookie = new HttpCookie(cookiePrefix);
cookie.Values[sessionKey.SessionKeyName] = sessionValue;
cookie.Expires = DateTime.Now.AddHours(1);
HttpContext.Current.Response.Cookies.Set(cookie);
}
What you're missing is that when you update the cookie with SetValue you're writing to the Response.Cookies collection.
When you call GetValue you're reading from the Request.Cookies collection.
You need to store the transient information in a way that you access the current information, not just directly the request cookie.
One potential way to do this would be to writer a wrapper class that with rough psuedo code would be similar to
public CookieContainer(HttpContext context)
{
_bobValue = context.Request.Cookies["bob"];
}
public Value
{
get { return _bobValue; }
set {
_bobValue = value;
_context.Response.Cookies.Add(new Cookie("bob", value) { Expires = ? });
}
}
I ran into needing to do similar code just this week. The cookie handling model is very strange.
Start using Sessions to store your information, even if it's only temporary.
Cookies rely on a header being sent to the browser before the page has rendered. If you've already sent information to the client then proceed to set a cookie, you're going to see this "page refresh delay" you've described.
If it's necessary to have this value, use a session variable between the time you set the cookie and when you refresh the page. But, even then I would just recommend avoiding settings cookies so late in the processing step and try to set it as early as possible.

ASP MVC Cookies not persisting

I have a ASP MVC App with some seemingly simple code to save and retrieve cookies but for some reason they won't persist. The code in the controller is :
if (System.Web.HttpContext.Current.Response.Cookies["CountryPreference"] == null)
{
HttpCookie cookie = new HttpCookie("CountryPreference");
cookie.Value = country;
cookie.Expires = DateTime.Now.AddYears(1);
System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
}
And to load it again :
if (System.Web.HttpContext.Current.Request.Cookies["CountryPreference"] != null)
{
System.Web.HttpContext.Current.Request.Cookies["CountryPreference"].Expires = DateTime.Now.AddYears(1);
data.Country = System.Web.HttpContext.Current.Request.Cookies["CountryPreference"].Value;
}
For some reason the cookie is always null?
The problem lies in following code:
if (System.Web.HttpContext.Current.Response.Cookies["CountryPreference"] == null)
When you try to check existence of a cookie using Response object rather than Request, ASP.net automatically creates a cookie.
Check this detailed post here: http://chwe.at/blog/post/2009/01/26/Done28099t-use-ResponseCookiesstring-to-check-if-a-cookie-exists!.aspx
Quote from the article in case the link goes down again ....
The short explanation, if you don’t
like to read the entire story
If you use code like “if
(Response.Cookies[“mycookie”] != null)
{ … }”, ASP.Net automatically
generates a new cookie with the name
“mycookie” in the background and
overwrites your old cookie! Always use
the Request.Cookies-Collection to read
cookies!
[ More detail in the article ]
In resume, don't use "Response" to read cookies, use "Request".

Resources