ASP.NET Response.Cookie client or server? - asp.net

When calling Response.Cookie.Add(new HttpCookie("MyCookie", "objValue")); where does the cookie saved? on Client Machine or Server Machine?
EDIT:
if saved in Client Machine, how can I read it from javascript then? I tried this kind of script.
function getCookie(c_name) {
var i, x, y, ARRcookies = document.cookie.split(";");
for (i = 0; i < ARRcookies.length; i++) {
x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
x = x.replace(/^\s+|\s+$/g, "");
if (x == c_name) {
return unescape(y);
}
}
}
I cannot get the cookie that I saved from code behind. When I look into the document.cookie object, it is just an empty string.
Scenario:
On Page_Init() on code behind. I create a cookie using Response.Cookie.Add(new HttpCookie("MyCookie", "cookieValue"));.
On Client side, I'm trying to read the cookie saved from code behind on page load using the snippet above, but it returns undefined

As Wikipedia explains, cookies string values that are stored on the client.
They are sent to server with each HTTP request as Cookie: headers.
You can store arbitrary objects in the server using session state.

Client machine. I'm sure google could give you a good explanation, But I use it everyday, and experience is my source.

Cookies are always saved at Client Machine.

Related

"Unable to determine a valid ordering for dependent operations" on production server

I have been working on a WCF web service, which is used by a mobile app that would send some data to it and save to DB.
One of the test case is that we try to append 2 (or more) records in the app, and the service is called to do a batch insert / update action.
Everything goes fine when I test using localhost, but when we test it using production server, only
the first record is saved, while the other record triggers the error message
Unable to determine a valid ordering for dependent operations...store-generated values.
I have no idea what is the cause and how to solve it. I have done some research and I am quite sure that the related model/DB table has NO circular dependency or self dependency.
Below is a snippet of the web service:
public void submit(List<SubmissionParameter> param){
using (var context = ObjectContextManager.AuditEnabledInstance){
foreach (var item in param){
ReadingSubmission readingSubmission = context.ReadingSubmissions.Where(p => p.ReadingSubmissionUniqueIdentifier == item.Readingsubmissionuniqueidentifier).SingleOrDefault();
if (readingSubmission == null){
readingSubmission = new ReadingSubmission();
context.ReadingSubmissions.AddObject(readingSubmission);
}
readingSubmission.ReadingSubmissionUniqueIdentifier = item.Readingsubmissionuniqueidentifier;
readingSubmission.SystemID = item.Systemid;
readingSubmission.UserID = item.Userid;
foreach (var record in item.Readings){
SystemReading systemReading = context.SystemReadings.Where(p => p.SystemReadingUniqueIdentifier == record.Systemreadinguniqueidentifier).SingleOrDefault();
if (systemReading == null){
systemReading = new SystemReading();
readingSubmission.SystemReadings.Add(systemReading);
}
systemReading.SystemReadingUniqueIdentifier = record.Systemreadinguniqueidentifier;
systemReading.MeasurementID = record.Measurementid;
}
context.SaveChanges();
}
}
}
ReadingSubmission and SystemReading is a 1 to many relation
SubmissionParameter is just a transmission object as the mobile client will send the JSON object to this web service.
I use Telerik Fiddler to post the JSON into this web service for testing, so I am quite sure the problem is not at the mobile client side.
Any help is appreciated! Thanks!
Finally I solve the problem though I am not quite sure why it works.
I move the context.SaveChanges() out of the foreach loop then it all works again for
both localhost and production
Hope it can help someone to save some time

asp.net app calling service says its not initialized?

So this code runs in an asp.net app on Linux. The code calls one of my services. (WCF doesn't work on mono currently, that is why I'm using asmx). This code works AS INTENDED when running from Windows (while debugging). As soon as I deploy to Linux, it stops working. I'm definitely baffled. I've tested the service thoroughly and the service is fine.
Here is the code producing an error: (NewVisitor is a void function taking 3 strings in)
//This does not work.
try
{
var client = new Service1SoapClient();
var results = client.NewVisitor(Request.UserHostAddress, Request.UrlReferrer == null ? String.Empty : Request.UrlReferrer.ToString(), Request.UserAgent);
Logger.Debug("Result of client: " + results);
}
Here is the error generated: Object reference not set to an instance of an object
Here is the code that works perfectly:
//This works (from the service)
[WebMethod(CacheDuration = _cacheTime, Description = "Returns a List of Dates", MessageName = "GetDates")]
public List<MySqlDateTime> GetDates()
{
return db.GetDates();
}
//Here is the code for the method above
var client = new Service1Soap12Client();
var dbDates = client.GetDates();
I'd love to figure out why it is saying that the object is not set.
Methods tried:
new soap client.
new soap client with binding and endpoint address specified
Used channel factory to create and open the channel.
If more info is needed I can give more. I'm out of ideas.
It looks like a bug in mono. You should file a bug with a reproducible test case so it can be fixed (and possibly find a workaround you can use).
Unfortunately, I don't have Linux to test it but I'd suggest you put the client variable in an using() statement:
using(var client = new Service1SoapClient())
{
var results = client.NewVisitor(Request.UserHostAddress, Request.UrlReferrer == null ?
String.Empty : Request.UrlReferrer.ToString(), Request.UserAgent);
Logger.Debug("Result of client: " + results);
}
I hope it helps.
RC.

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

RIA Services, Forms Authentication and extra cookies

I have an Silverlight 4 RIA Services application with custom Forms Authentication. The custom authentication service works like a charm.
The problems is I want to serialize the user object in a cookie which is then sent with each subsequent request.
I create the cookie and add it to the response cookie collection but on the next request the only cookies in the cookie collection are ASPXAUT and ASPX_SESSIONId, of the custom cookie not a trace.
This is the cookie management class:
public class CookieManager:ISessionManager
{
public object this[string key]
{
get
{
var context = getCurrentContext();
var cookie = context.Request.Cookies[key];
if (cookie == null) return null;
return deserialize(cookie.Value);
}
set
{
var context = getCurrentContext();
string cookieValue = serialize(value);
HttpCookie cookie = new HttpCookie(key, cookieValue);
cookie.Expires = DateTime.Now.AddDays(10000);
cookie.HttpOnly = false;
context.Response.Cookies.Remove(key);
context.Response.Cookies.Add(cookie);
}
}
public void Abandon()
{
var context = getCurrentContext();
context.Response.Cookies.Clear();
}
public void Clear()
{
Abandon();
}
private HttpContext getCurrentContext()
{
return HttpContext.Current;
}
private string serialize(object value)
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
formatter.Serialize(stream, value);
StreamReader reader = new StreamReader(stream);
stream.Position = 0;
string result = reader.ReadToEnd();
reader.Close();
stream.Close();
return HttpUtility.UrlEncodeUnicode(result);
}
public object deserialize(string value)
{
value = HttpUtility.UrlDecode(value);
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(value);
BinaryFormatter formatter = new BinaryFormatter();
return formatter.Deserialize(stream);
}
}
It reads and saves cookies.
Now my problem is this:
What I need to enable in silverlight or in the ASP.NET (WCF) application in order for extra cookies to be sent with each request along side the authentication cookie.
EDIT:
I've inspected the HTTP request/response stack and those extra cookies are sent from the server with the WCF RIA Services response but not returned by the next service call from the client.
If I understand your edit above correctly, you've already inspected the HTTP requests and found the desired cookie present in the HTTP Set-Cookie header of the response, but missing in the Cookie header of the next request. Is this correct? If not, please clarify.
If so, the problem sounds like one of three things:
the client is not successfully saving the cookie, due to many possible reasons including:
cookie not properly formatted (unlikley)
cookie is too long
there's a client- or server-side policy (e.g. P3P) preventing saving persistent cookies.
The client is saving the cookie OK, but is not sending it back, even without Silverlight. This could be caused by, for example, a security issue where the hostname of the first request is different from the second.
The client is saving the cookie and can send it back over regular HTML pages, but not via HTTP requests sent by Silverlight.
To see if #1 is the problem, look (using your browser's ability to view cookies) at the cookies saved by your browser for that site. Is the expected cookie saved? If it is, then you can eliminate #1 as the problem. If it's not saved, start looking
To see if #2 is the problem, try creating a server-side page with no silverlight on it-- just a simple HTML page. When you visit that page with your browser, is the cookie sent as expected? If yes, then #2 is not your problem.
If #1 and #2 are not the problem, that leaves #3. Silverlight's HTTP handling is complicated, not least because you have to choose between having HTTP client requests handled by the browser or by Silverlight. Read the Silverlight cookies documentation carefully and see if any of the info therein will help you figure out the problem. Consider trying to use the "Client HTTP" setting, or if you're already using this, consider switching back to the "browser HTTP" setting and see if your problem goes away. Note that the Client HTTP setting apparently has a problem with losing new cookies after an HTTP redirect. See this thread for more info. There's a workaround discussed in that thread: using CookieContainer.
BTW, could you edit your question to include all the HTTP headers of the request and the subsequent request? This may help diagnosis.

Relationship between HttpContext.Request.Cookies and HttpContext.Response.Cookies

I have been experimenting with code that will clear all of the cookies in an HttpContext.Response.
Initially, I used this:
DateTime cookieExpires = DateTime.Now.AddDays(-1);
for (int i = 0; i < HttpContext.Request.Cookies.Count; i++)
{
HttpContext.Response.Cookies.Add(
new HttpCookie(HttpContext.Request.Cookies[i].Name, null) { Expires = cookieExpires });
}
However, this will error with an OutOfMemoryException because the for loop never exits - each time you add a cookie to the Response, it also gets added to the `Request.
The following approach works:
DateTime cookieExpires = DateTime.Now.AddDays(-1);
List<string> cookieNames = new List<string>();
for (int i = 0; i < HttpContext.Request.Cookies.Count; i++)
{
cookieNames.Add(HttpContext.Request.Cookies[i].Name);
}
foreach (string cookieName in cookieNames)
{
HttpContext.Response.Cookies.Add(
new HttpCookie(cookieName, null) { Expires = cookieExpires });
}
So, what exactly is the relationship between HttpContext.Request.Cookies and HttpContext.Response.Cookies?
Request.Cookies contains the complete set of cookies, both those that browser send to the server and those that you just created on the server.
Response.Cookies contains the cookies that the server will send back.
This collection starts out empty and should be changed to modify the browser's cookies.
The documentation states:
ASP.NET includes two intrinsic cookie
collections. The collection accessed
through the Cookies collection of
HttpRequest contains cookies
transmitted by the client to the
server in the Cookie header. The
collection accessed through the
Cookies collection of HttpResponse
contains new cookies created on the
server and transmitted to the client
in the Set-Cookie header.
After you add a cookie by using the
HttpResponse.Cookies collection, the
cookie is immediately available in the
HttpRequest.Cookies collection, even
if the response has not been sent to
the client.
Your first code sample should work if you make the for loop run backwards.
The new cookies will be added after the end, so the backwards loop would ignore them.

Resources