ASP MVC Cookies not persisting - asp.net

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".

Related

How to handle Session on each request Asp.net mvc

I have an web application running in mobile application(WebView).When user open the app, mobile app sends me the language info of the telephone through the request. Since the language value comes only on the first request and then deleted, I have to take it and store it for subsequent requests. I have tried PreRequestHandlerExecute and Application_AcquireRequestState on global.asax. I control the Session. if it is null I get the value from request, if it is not null I get it from session. But it seems like session is always null and always get the value from request. Any idea would be very helpful? Thanks for advance.
var dilKodu = Request.Headers.GetValues("languageCode");
CultureInfo ci;
if (dilKodu != null)
{
//I set culture from request if it is not null.
ci = new CultureInfo(dilKodu[0].ToString());
this.Session["Culture"] = ci;
}
else
{
if (HttpContext.Current.Session != null)
{
//I get culture from Session if its set before.
ci = (CultureInfo)this.Session["Culture"];
if (ci == null)
{
string langName = "tr";
//If culture exist neither Session nor Request
ci = new CultureInfo(langName);
this.Session["Culture"] = ci;
}
}
else
{
ci = new CultureInfo("tr");
}
}
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
Going by your code you are always going into the first if statement which will read and set the code form dilKodu
Your code should be more like this
if (HttpContext.Current.Session != null)
{
ci = (CultureInfo) this.Session["Culture"];
if (ci == null)
{
var langName = Request.Headers.GetValues("languageCode");
Session["dilG"] = langName;
ci = new CultureInfo(langName);
Session["Culture"] = ci;
}
}
else
{
Session["dilG"] = "session hazır değil tr yapıldı";
ci = new CultureInfo("tr");
}
Basically you have the if statements incorrectly setup for what you are trying to do.
Also it might be advisable to keep your session objects small, that is just store langName in the session and create a CultureInfo from that each time rather than store CultureInfo.
Is this an MVC web app? If so, you could try to save the value in the Controller.TempData property.
So instead of doing this.Session["culture"] = ci; you would add to the TempData property TempData.Add("culture", ci);. This would make the culture available for the next request. You would just need to make sure that you re-add the ci value in each request to make the value persist for as long as you need it.
Documentation for TempDataDictionary: https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.tempdatadictionary?view=aspnet-mvc-5.2
It was bcause of a setting in the web.config.
<httpCookies requireSSL="true" httpOnlyCookies="true"/>
I was trying to secure cookie but it prevent sessions. I delete it and now everything is works just fine. But I still need to find a way to secure cookies.

I can't read cookies in master or other pages

I create some cookies in logon.aspx.cscodebehind thatc read and contain user info from DB with data reader .
HttpCookie UID = new HttpCookie("ID");
Response.Cookies["UID"].Value = Recordset[0].ToString();
Response.Cookies.Add(UID);
HttpCookie UName = new HttpCookie("Username");
Response.Cookies["Username"].Value = Recordset[3].ToString();
Response.Cookies.Add(UName);
HttpCookie Pass = new HttpCookie("Pass");
Response.Cookies["Pass"].Value = Recordset[4].ToString();
Response.Cookies.Add(Pass);
HttpCookie Admins = new HttpCookie("Admin");
Response.Cookies["Admin"].Value = Recordset[12].ToString();
Response.Cookies.Add(Admins);
HttpCookie Mails = new HttpCookie("Emails");
Response.Cookies["Emails"].Value = Recordset[9].ToString();
Response.Cookies.Add(Mails);
Response.Redirect("../default.aspx");
when i trace the code every thing is good and data hold by cookies.
Now when i read these cookies in master page or other content page, i can't.
in other worlds the cookies not recognize by their names(or keys)
if (Request.Cookies["Username"] !=null)
{
lblWelcomeUser.Text = Server.HtmlEncode(Request.Cookies["Username"].Value);
pnlUsersNavigation.Visible = true;
LoginMenu.Visible = false;
RegisterMenu.Visible = false;
lblWelcomeUser.Text = Server.HtmlEncode(Request.Cookies["Username"].Value);
//lblWelcomeUser.Text = Request.Cookies["Username"].Value.ToString();
if (Request.Cookies["Admin"].Value.ToString()=="True")
{
lblWelcomeUser.Text = "WELCOME ADMIN";
// Show Menu that is only for Admin
}
where is the problem in this code?
It appears that you might be overwriting the cookie with a good value, with a new empty cookie.
// new cookie created - empty
HttpCookie UName = new HttpCookie("Username");
// new cookie created with a value
Response.Cookies["Username"].Value = Recordset[3].ToString();
// overwrite new cookie with value with new empty cookie
Response.Cookies.Add(UName);
Create the cookie, set the value, then add the cookie to the response.
HttpCookie UName = new HttpCookie("Username");
UName.Value = Recordset[3].ToString();
Response.Cookies.Add(UName);
Also note that as Paul Grimshaw pointed out, you can add multiple values to the same cookie.
Download Fiddler to check request/response to ensure your cookies contain the correct values and such... http://fiddler2.com/get-fiddler
Also be careful about Man-in-the-middle attacks. Storing usernames and passwords in plain text is not such a good idea to begin with.
This doesn't look like a very secure way of securing access to your application. Try looking at ASP.NET membership.
Otherwise try setting an expiry date. Also, as this example shows, you may want to store all the above info in one cookie:
HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["UID"] = Recordset[0].ToString();
myCookie["Username"] = Recordset[3].ToString();
//...etc...
myCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(myCookie);
Also, from MSDN:
By default, cookies are shared by all pages that are in the same
domain, but you can limit cookies to specific subfolders in a Web site
by setting their Path property. To allow a cookie to be retrieved by
all pages in all folders of your application, set it from a page that
is in the root folder of your application and do not set the Path
property. If you do not specify an expiration limit for the cookie,
the cookie is not persisted to the client computer and it expires when
the user session expires. Cookies can store values only of type
String. You must convert any non-string values to strings before you
can store them in a cookie. For many data types, calling the ToString
method is sufficient. For more information, see the ToString method
for the data type you wish to persist.

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. :)

Spoofing HTTP Referrer data using ASP.NET

Answers on here and various other sites are often full of warnings not to trust HTTP Referrer headers because they are 'so easily' spoofed or faked.
Before I go any further - no, I'm not up to no good - but I do want to run some referrer-dependant tests.
Whilst I don't doubt that the warnings about fake referrers are true, I can't really find much detailed info on how they can be manipulated. Even the Wikipedia article only talks about it in general terms.
I'm about to play with the RefControl addin for FireFox.
Programatically (in ASP.NET specifically) the UrlReferrer is a read-only property, so I don't see how I can fire off requests with fake referrer data if I can't set it? Do I really have to do it manually?
How would I use ASP.NET to send a request to my site with a user-supplied variable to populate the referrer header?
EDIT : As per my comment below, I ideally want to take an incoming request, manupulate the referrer data and then pass the request on to another page, intact. If I can make it appear intact by building a new one from scratch and copying the original properties, then that is fine too.
I don't know if this exactly what you want, but in general, you should be able to spoof the value of the UrlReferer property (even if it's read-only) in HttpContext.Current.Request by using a bit of reflection.
For example:
FieldInfo fi = HttpContext.Current.Request.GetType().GetField("_referrer", BindingFlags.NonPublic | BindingFlags.Instance);
string initialReferer = HttpContext.Current.Request.UrlReferrer.ToString();
if (fi != null)
fi.SetValue(HttpContext.Current.Request, new Uri("http://example.com"));
string fakedReferer = HttpContext.Current.Request.UrlReferrer.ToString();
On VS; these are the values before and after changing the UrlReferrer:
initialReferer
"http://localhost/Test/Default.aspx"
fakedReferer
"http://example.com/"
If you open the System.Web assembly using ILSpy you'll notice that the UrlReferrer property looks something like this:
public Uri UrlReferrer
{
get
{
if (this._referrer == null && this._wr != null)
{
string knownRequestHeader = this._wr.GetKnownRequestHeader(36);
if (!string.IsNullOrEmpty(knownRequestHeader))
{
try
{
if (knownRequestHeader.IndexOf("://", StringComparison.Ordinal) >= 0)
{
this._referrer = new Uri(knownRequestHeader);
}
else
{
this._referrer = new Uri(this.Url, knownRequestHeader);
}
}
catch (HttpException)
{
this._referrer = null;
}
}
}
return this._referrer;
}
}
This likely isn't going to get you what you want. But you can edit the Referror of an HttpWebRequest. I don't think there is a way of editing the referrer of your request in context.
using System.Net;
HttpWebRequest Req= (HttpWebRequest)System.Net.HttpWebRequest.Create("http://somewhere.com/");
Req.Referer = "http://www.fakesite.com";

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.

Resources