Error retrieving information from user cookie - c#

When I run the project, I get this line highlighted with an error:
string cartID = context.Request.Cookies["Cinemax_CartID"].Value;
The message is as follows:
Object reference not set to an instance of an object.
Thanks for any suggestions!

The problem is that you have to check if the cookie exists, if it does, then you can read its value in a safe way, otherwise you should initialize the cookie value or you would get a null reference exception.
This is actually the same pattern you should apply when reading items from the ViewState, Session, Application, Cookies, etc. basically you cannot rely on an external value, you should check if it actually exists
Try something like this:
if(context.Request.Cookies["Cinemax_CartID"] == null)
{
// initialize the cookie
context.Request.Cookies["Cinemax_CartID"].Value = initial_value;
}
myCookieValue = context.Request.Cookies["Cinemax_CartID"].Value;

Related

Reading a cookie that has just been written causes the cookie to be blanked

Okay so this one has me stumped. I have written a function that reads the value of a cookie. The logic is
check Response.Cookies in case it has just been written
otherwise read from Request.Cookies to get the previous value
If the cookie has just been written then all is good, and I get the value. However if the cookie has not been written on this visit - it appears to blank the value of the already store cookie.
What?
Here is the code
Note the write happens in a controller
public static void PersistCookie(string cookieName, string cookieValue, bool persistent)
{
var cookie = new HttpCookie(cookieName, cookieValue)
{
Path = "/",
HttpOnly = true,
};
if (persistent)
cookie.Expires = DateTime.Now.AddMonths(6);
HttpContext.Current.Response.SetCookie(cookie);
}
Note the read happens ina partial view
public static string ReadCookieValue(string cookieName, bool checkResponseFirst)
{
if (checkResponseFirst && HttpContext.Current.Response.Cookies[cookieName] != null &&
HttpContext.Current.Response.Cookies[cookieName].Value.HasValue())
return HttpContext.Current.Response.Cookies[cookieName].Value;
return HttpContext.Current.Request.Cookies[cookieName] != null ? HttpContext.Current.Request.Cookies[cookieName].Value : "";
}
It almost seems that just by checking if a cookie has a value, it messes things up.
Thoughts?
Okay so after much more searching on the web, a good work colleague cam up with the following
it looks like I have come across a curiosity in .NET.
Check out this article
http://www.codeproject.com/Articles/3106/On-The-Care-and-Handling-of-Cookies
If you try to access a cookie that doesn't exist in the Response.Cookies collection, it will be created with an empty string in the Value and an Expires date of 01-Jan-0001 00:00. Strangely, it also creates a matching cookie in the Request.Cookies collection if one doesn't already exist.
So if you look at a cookie in the Response then you are indirectly overwriting the cookie on the client machine with an empty cookie, due to expire when the browser closes
So my problem is solved (or should that be unsolvable). As it turns out I have a workaround using the ViewBag but I am glad I was not going crazy!
Thanks for you help
I am not sure you can set cookies in partial views. When setting the cookie with Response.SetCookie, the information is returned to the browser in the Set-Cookie HTTPHeader field. I don't think partial views can set this value, try inspecting your applications response with Fiddler2, after calling Response.SetCookie.
I usually set my cookies with plain Javascript.

setting HttpContext.Current.User throws null reference exception

This is a WCF Oneway operation. HttpContext.Current.User is cleared in those operations, that is the reason I added a behavior that saves the User before it is cleared. Later I want to re-set the HttpContext.Current.User with the value I saved but I'm getting an exception:
HttpContext.Current.User = (RolePrincipal)userThatWasSavedBefore;
Object reference not set to an instance of an object.
at System.Web.HttpContext.SetPrincipalNoDemand(IPrincipal principal, Boolean needToSetNativePrincipal)
at System.Web.HttpContext.set_User(IPrincipal value)
at (My Function)
Why can't I set the user? What is the problem?
The reason you can't set it is most likely that the request has finished. Setting the User property results in ASP.NET trying to call back into per-request data structures, and if these data structures have been released then the resulting behavior is undefined.
For one-way operations, WCF invokes application code while simultaneously telling ASP.NET not to wait for the application code to finish and to just complete the request immediately. For this reason is it strongly recommended that you don't access HttpContext from a one-way operation.
Clearly some object in the line throwing the exception is null.
Check whether you have a current HttpContext, that is, I suspect HttpContext.Current is null.
The call stack shows an instance method of HttpContext is executed.
In other words - HttpContext is there, the exception is provoked by something else - a missing NulRef check likely for _notificationContext.
The NotificationContext is internal and unset only by OnRequestNotificationCompletionHelper as I write.
Exception scenario seem to look like:
Some work is to be done async - does not block/prevent a request from being completed
Request processing is finished
Your worker item sets HttpContext.User for the finished request
This looks like a framework bug :(
This problem is either because some object in these classes is null (such as HttpContext.Current)
OR
The user which you are passing there (and you saved before) is actually pointing to null. As you can see from stack trace, this is very likely the case, because the exception is thrown by System.Web.HttpContext.set_User(IPrincipal value)
User is actually not a variable, but a property. And changing it to another value is calling a function, that throws this exception in case new value for user is null.
In order to find out what is causing this problem I recommend you to set a breakpoint to the line which is throwing the exception and check if any part of that line isn't pointing to null
crash proof alternative could be:
if (HttpContext.Current != null && userThatWasSavedBefore != null)
{
HttpContext.Current.User = (RolePrincipal)userThatWasSavedBefore;
}

Difference between HttpResponse: SetCookie, AppendCookie, Cookies.Add

there are some different ways to create multi value cookies in ASP.NET:
var cookie = new HttpCookie("MyCookie");
cookie["Information 1"] = "value 1";
cookie["Information 2"] = "value 2";
// first way
Response.Cookies.Add(cookie);
// second way
Response.AppendCookie(cookie);
// third way
Response.SetCookie(cookie);
When should I use which way? I've read that SetCookie method updates the cookie, if it already exits. Doesn't the other ways update the existing cookie as well?
And is the following code best practice for writing single value cookies?
Response.Cookies["MyCookie"].Value = "value";
If I remember correctly both
Response.Cookies.Add(..)
and
Response.AppendCookie(..)
will allow multiple cookies of the same name to be appended to the response.
On the other hand
Response.SetCookie(..)
and
Response.Cookies[key].Value = value;
will always overwrite previous cookies of the same name.
When should I use which way?
It's depends on what Cookie operation you want to do.
Note that Add and AppendCookie are doing the same functionality except the fact that with AppendCookie you're not referencing the Cookies property of the Response class and it's doing it for you.
Response.Cookies.Add - Adds the specified cookie to the cookie
collection.
Response.AppendCookie - Adds an HTTP cookie to the
intrinsic cookie collection
Response.SetCookie - Updates an existing cookie in the cookie
collection.
Exceptions will not be thrown when duplicates cookies are added or when attempting to update not-exist cookie.
The main exception of these methods is: HttpException (A cookie is appended after the HTTP headers have been sent.)
The Add method allows duplicate cookies in the cookie collection. Use the Set method to ensure the uniqueness of cookies in the cookie collection.
Thanks for MSDN!
To piggyback on tne's comment in Wiktor's reply, AppendCookie and SetCookie shouldn't be used - they're for internal use by the .NET framework. They shouldn't be public but they are, my guess would be as a hack for the IIS pipeline somewhere else.
So you should do your cookie setting this way (or write an extension method for setting multiple cookies):
string cookieName = "SomeCookie";
string cookieValue = "2017";
if (Response.Cookies[cookieName] == null)
{
Response.Cookies.Add(new HttpCookie(cookieName, cookieValue));
}
else
{
Response.Cookies[cookieName].Value = cookieValue;
}

Session not getting retrieved in Facebook C# SDK example

I am a newbie at ASP.net programming. This is in reference to the Facebook C# SDK, I have managed to set up all the steps required for authentication on this SDK. However, I keep getting a null from the following code:
(reference: http://csharpsdk.org/docs/web/getting-started#5)
var accessToken = Session["AccessToken"].ToString(); //This line returns null and crashes
var client = new FacebookClient(accessToken);
dynamic result = client.Get("me", new { fields = "name,id" });
string name = result.name;
string id = result.id;
Just like in the example, I had set up a generic handler to set up the session variable to be stored in the HttpContext.Session object.
I even tried to modify the offending line to directly access the HttpContext and retrieve the access token:
var accessToken = HttpContext.Current.Session["AccessToken"].ToString();
but this yielded the same result.
Have I missed out something in the webconfig or is there some other way I can store the access token when shifting from the handler to the log in page?
Make sure in your Facebook developer settings that you do not have query string selected for your app as auth token paramenter!!!
This is the default mode and this wont work unless you do the following:
http://developer.facebook.com
Open your app page.
Then go Settings --> Auth Dialog --> Auth Token Parameter and select URI Fragment.
100% sure this is your problem. It's not included in any literature I found, and it's a damn shame.
If it is returning null then I would assume that the Session value is not being set - have you debugged to make sure the code which sets the session is being hit?
Looking at the linked article - it uses a HttpHandler to do this bit but does not mention anything about registering it in the Web.Config - have you done this? If not see here http://msdn.microsoft.com/en-us/library/46c5ddfy.aspx

Object reference error even when object is not null

i have an application wherein i have incorporate a "Remember Me" feature for the login screen.
I do this by creating a cookie when the user logs in for the first time, so next time when the user visits the site i get the cookie and load the user information.
i have written the code for loading user information in a common class in the App_Code folder...and all my pages inherit from this class.
code for loading the user info is as follows:
public static void LoadUserDetails(string emailId)
{
UsersEnt currentUser = UsersBL.LoadUserInfo(emailId);
if (currentUser != null)
HttpContext.Current.Session["CurrentUser"] = currentUser;
}
Now the problem is i get an "Object reference" error when i try to store the currentUser object in the session variable (even though the currentUser object is not null). However the password property in the currentUser object is null.
Am i getting the error because of this...or is there some other reason??
thank you
Assuming it's the final line which is causing the problem, that suggests that either HttpContext.Current or HttpContext.Current.Session is null. I suggest you find out which it is, and then work out why.
HttpContext.Current.Session is probably null.
Code that uses the State has to be placed after the AcquireRequestState Event has called. See the page lifecycle for more information.
Try putting your code after or inside the Page_Load method.
If it is throwing the exception on the line:
HttpContext.Current.Session["CurrentUser"] = currentUser;
Then the only other explanation is that HttpContext.Current.Session is null.

Categories