cookie values disappear when traversing between content pages - c#

in my app. there's a log in mechanism which save a cookie with the info of the user who just logged in
private void CreateCookie(LoginEventArgs args)
{
HttpCookie cookie = new HttpCookie("user");
cookie.Values["name"] = args.User_Name;
cookie.Values["id"] = args.ID;
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
}
on my master page load i perform a check to see if this cookie exists or not :
HttpCookie cookie = Request.Cookies["user"] ;
if( (cookie != null) && (cookie.Value != ""))
{
if (Session["user"] == null)
Login_Passed(this, new LoginEventArgs(cookie.Values["name"].ToString(), int.Parse(cookie.Values["id"])));
}
now if i Log in ( Create A cookie ) , close the browser , and run my app. again the cookie
exists it's values are correct and the user is "automatically" logged in .
if i first redirect to a different content page from the start up content page
the cookies values are also intact ,
the problem is when i redirect back to a different content page a second time,
the master page loads , makes the check
the cookie exists but the values are deleted ...
any ideas on why this happens ?
btw maybe the way i log out could be the reason for this problem :
when i log-out i create a cookie with the same name that expires 1 day ago .
private void Remove_Cookie()
{
HttpCookie cookie = new HttpCookie("user");
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
}
in the case iv'e described i don't log-out formally , i just end my app , so this shouldn't
have any effect .

o'k , the problem was unthinkable
special thanks to Peter Bromberg
http://www.eggheadcafe.com/tutorials/aspnet/198ce250-59da-4388-89e5-fce33d725aa7/aspnet-cookies-faq.aspx
in the section of the Article " The Disappearing Cookie "
the author states that if you have a watch on Response.Cookies["cookie_name"]
the browser creates a new empty cookie that overrides your cookie .
i used such a watch which made my cookie loose it's values ,and when i took it off the cookie kept its values.
the moral is DON't WATCH Response.Cookies[" "]
also i read in some other post that if you check
if( Response.Cookies["cookie_name"] != null )
for example it also gets overridden.

To reiterate and build upon what has already been stated (yes, I know this is a 4 year old question) I have found it best to build a utility to handle this - mostly because I want to check that specific cookie often.
This will not touch the Response but only read from the Request.
public static HttpCookie GetCookie(string cookieName)
{
HttpCookie rqstCookie = HttpContext.Current.Request.Cookies.Get(cookieName);
/*** NOTE: it will not be on the Response!
* this will trigger the error noted in the original question and
* create a new, empty cookie which overrides it
*
HttpCookie respCookie = HttpContext.Current.Response.Cookies.Get(cookieName);
*
*/
if (rqstCookie != null && !String.IsNullOrEmpty(rqstCookie.Value))
{
// is found on the Request
return rqstCookie;
}
else
{
return null;
}
}
rule-of-thumb
Always read from the Request and write to the Response.
Thanks eran! this post was exactly what I needed

try the following:
If you are developing on your local machine, put your app on some free web page, so there will be no 'special treatment' because you're in the local host.
If you already are on a web-server, and if the re-directions are between tow different domains, you may want to search google for 'same origin policy' or read this: http://en.wikipedia.org/wiki/Same_origin_policy (the document talks about javascript, but its true also for cookies).

Use the following approach to get a value from cookies:
public string GetValueFromCookies(HttpCookieCollection cookies)
{
if (cookies == null)
{
throw new ArgumentNullException(nameof(cookies));
}
// check the existence of key in the list first
if (Array.IndexOf(cookies.AllKeys, key) < 0)
{
return null;
}
// because the following line adds a cookie with empty value if it's not there
return cookies[key].Value;
}

Related

how to make cookie in asp.net that takes url query string

intern in company working with asp.net and sitecore here
My very first assignment has to do with adding support for a query parameter that can will enable the editor to see some key names of some buttons for a page.
Now i was thinking that i would make a cookie with httpcookie in the correct controller and somehow get the query parameter into the cookie, could that be done in a way?
many thanks?
You can use a URL querystring parameter to get the value you need on Page Load and then set controls accordingly. As for storing Values you can store whatever you need in ViewState or SessionState and look them up when you need to.
Example below:
private void Page_Load()
{
if(Request.QueryString["switch"] !== null)
{
if(Request.QueryString["switch"].ToString()) == "on")
{
button.Visible = true;
ViewState["someval"] = hiddenVal.Text;
}
else
{
button.Visible = false;
}
}
}

Is there a way to set Master Page after reading query and session?

I was able to set Master Page programmatically in Page_PreInit like:
Page.MasterPageFile = "Site.Master";
Since I can't read a session variable just set and change in every page load before or while this phase a code like the following didn't work to set different Master Page according to session variable which based on a URL query string:
if (Session["PageLayout"] != null) {
if (Session["PageLayout"].ToString() == "1") {
Page.MasterPageFile = "FullWidth.Master";
} else if (Session["PageLayout"].ToString() == "2") {
Page.MasterPageFile = "SideBar.Master";
} else {
Page.MasterPageFile = "Site.Master";
}
}
Wonder how to set Page Master in ASP.NET C# based on session or query string passed on page load!
Update: I have tried using the solution in this question
but the problem is that in the other question the session generated while login and is used in another page while in my case the session value only available after visiting the page and based on the URL query / page ID or maybe I couldn't implement it the same way.

Optimizing the cookie expiration code

I wrote the following code to expire all the cookies in my request. But along with expiring them, I need to set the domain property for some of the cookies explicitly. I was wondering if there is a better way to do the same...
protected void Page_Load(object sender, EventArgs e)
{
Session.Abandon();
HttpCookie cookie;
string cookieName;
int cookieCount = Request.Cookies.Count;
for (int i = 0; i < cookieCount; i++)
{
cookieName = Request.Cookies[i].Name;
cookie = new HttpCookie(cookieName);
cookie.Expires = DateTime.Now.AddDays(-1);
if (string.Compare(cookieName, "cookie1") == 0
|| string.Compare(cookieName, "cookie2") == 0
|| string.Compare(cookieName, "cookie3") == 0
|| string.Compare(cookieName, "cookie4") == 0)
{
cookie.Domain = ".mydomain.com";
}
Response.Cookies.Add(cookie);
}
Response.Redirect("my redirect link");
}
I am new to C# so not sure if there is any other better way to set the domain value to the selected list of cookies only. I am from scripting background, basically from tcl and there usually I can simply check if the given item is in the list or not like:
if ($item in $list){
// Do something
}
which is similar to performing lsearch.
Anyways, the reason I don't like the logical operators in if is because in future i might have more cookies in the list to perform the same action and I don't want to keep stuffing the if condition checks.
I can probably do the same here as tcl like have a list of all the cookie names and then in for loop check for each cookie name in the list, but not sure how expensive it is.
Any comments would be appreciated.
You use new HttpCookie to create a new cookie. Therefor the domain of the existing Cookie is not copied. You'd be better off updating the existing cookie. For example at: Remove and delete all cookies of my ASP NET c-sharp application
Copied the code below from the url above:
foreach (string key in Request.Cookies.AllKeys)
{
HttpCookie c = Request.Cookies(key);
c.Expires = Now.AddMonths(-1);
Response.AppendCookie(c);
}
You can invalidate a Cookie by setting the expires date to a date in the past.

Storing "remember me" information locally c# (total newbeginner)

I started programming in c# for a few days ago, so I am a total newbeginner at this. Based on my experience in other languages, I found it somewhat "simple".
I am building a system where users are logging in to my application, which is working. I want to have a "remember me"-setting where the information is stored locally. What is the best way to do this? I'll only save the username and the password-hash.
Edit: This is a desktop-application. The login-information is sent to a php-script simply using HttpWebRequest
You can use the ConfigurationManager Class to manage your application's settings.
you can use this function to add new Keys to your configuration file:
public bool setSetting(string pstrKey, string pstrValue)
{
Configuration objConfigFile =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
bool blnKeyExists = false;
foreach (string strKey in objConfigFile.AppSettings.Settings.AllKeys)
{
if (strKey == pstrKey)
{
blnKeyExists = true;
objConfigFile.AppSettings.Settings[pstrKey].Value = pstrValue;
break;
}
}
if (!blnKeyExists)
{
objConfigFile.AppSettings.Settings.Add(pstrKey, pstrValue);
}
objConfigFile.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
return true;
}
and then save up your username (for example)
setSetting("username", usernameTextBox.Text);
Once your application starts up, you can read the information you saved earlier from your ConfigurationManager
usernameTextBox.Text = ConfigurationManager.AppSettings["username"];
you can create Application Settings in C#
here's what you will do.
don't forget to encrypt it.
If you're using ASP .NET,you can set authentication cookie when you're logged in user by second parameter
FormsAuthentication.SetAuthCookie(model.UserName, true);
Second parameter sets cookie to your request and makes "Remeber Me" option.
What I understand from your question is, php file is server and for client you are using windows form. Your are doing some kind of HTML scrapping and displaying the result HTML in your win-form. If this is the what you are doing then
//1. Create a dictionary to store cookie collection
public static Dictionary<string, Cookie> CookieCollection { get; set; }
//2. Store cookie in that collection
foreach (Cookie clientcookie in response.Cookies)
{
if (!CookieCollection.ContainsKey("AuthCookieName"))
CookieCollection .Add(userName, clientcookie);
else
CookieCollection ["userName"] = clientcookie;
}
//3. If remember me is clicked then send the same while creating request
request.CookieContainer.Add(request.RequestUri,
new Cookie("AuthCookieName", CookieCollection ["userName"]));
Where AuthCookieName is the name of authentication cookie. The only downside is when the application exists all the cookie stored in the dictionary would be gone. The solution could be serializing the cookie and storing it in database, if remember me is checked.

This .NET code snippet will NOT actually create a cookie, right?

I just realized that this cookie is not showing up like it should, and I checked the code which was not written by me but I am pretty sure that this is NOT enough to create a cookie right??
public static void CreateSSOCookies(string tokenID)
{
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Domain = System.Web.HttpContext.Current.Request.ServerVariables["SERVER_NAME"].ToString().ToLower();
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Value = tokenID.ToString();
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Path = "~/";
System.Web.HttpContext.Current.Response.Cookies["ssocookies"].Expires = DateTime.Now.AddDays(7);
}
If it does work, where is the cookie then? Is the cookie name 'ssocookies' ?
I must admit I didn't know, but apparently it does create a cookie. I've tested it, it works.
See http://msdn.microsoft.com/en-us/library/78c837bd.aspx
So far I had always used the new HttpCookie() method, which seems much .NET-like to me than a collection magically adding a cookie with the right name on first reference. I would still recommend being more explicit about creating the cookie like that, especially seeing some of the incorrect answers here :)
Edit:
The path "~/" is indeed probably not what you want. Use
// Removed some of the current context stuff for readability
Response.Cookies["ssocookies"].Path = VirtualPathUtility.ToAbsolute("~");
instead.
I think David, commenting on the question, is correct, but to expand on his comment:
The "~/" bit is specific to ASP.NET and won't resolve the path you'd expect. Therefore, the cookie is actually being created, but since you're setting the path to something invalid, it isn't getting returned back to you.
For example, if you set the path to "/foo", the cookie would only be returned on a request to the path /foo in your application.
Since there is no absolute path in your application equal to the literal ~/, the cookie won't be returned.
It does create a cookie. Looking in reflector, your code above is calling this:
public HttpCookie this[string name]
{
get
{
return this.Get(name);
}
}
which in turn calls:
public HttpCookie Get(string name)
{
HttpCookie cookie = (HttpCookie) base.BaseGet(name);
if ((cookie == null) && (this._response != null))
{
cookie = new HttpCookie(name);
this.AddCookie(cookie, true);
this._response.OnCookieAdd(cookie);
}
return cookie;
}
And you can see that it, in fact does, create a cookie. If you are not seeing it come back in the request, I think it has to do with your path. I am not sure "~/" is valid.
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["Font"] = "Arial";
myCookie["Color"] = "Blue";
myCookie.Expires = DateTime.Now.AddDays(1d);
Response.Cookies.Add(myCookie); //<<<<<<<<<-------------------
http://msdn.microsoft.com/en-us/library/78c837bd(v=VS.80).aspx

Categories