My Session variable is always null - c#

I'm creating a movie ticket reservation project. I want to get username from page1 and display it on page2 (using session variable)
Page1:
string uname = TextBox1.Text;
Session["UName"] = uname;
Session.Timeout = 30;
Page2:
if ((string)Session["UName"] != null)
{
string user = (string)Session["UName"];
}
and I placed a sign out button in page2 to remove session variable value. But the session variable is always null.
I've already used cookies in the page1 and will this be a cause? or what else? Please Help. Thanks in advance.

This usually occurs when doing a Response.Redirect after setting the session variable. You can work around this issue by calling the overload instead:
Response.Redirect("...", false); // false = don't stop execution
//causes ASP.NET to bypass all events and filtering in the HTTP pipeline
//chain of execution and directly execute the EndRequest event
HttpContext.Current.ApplicationInstance.CompleteRequest();
The underlying issue is a ThreadAbortException which is often ignored because it doesn't break the application. This is a known issue, and you can learn more about it here: http://support.microsoft.com/kb/312629.
Side Note
On a side note, you shouldn't be resetting your Session.Timeout value in the code like that. I can't be sure, but that may also have an adverse affect on your logic. Instead, you should specify the session timeout in the web.config under the system.web section:
<sessionState timeout="60" />

See this answer on when the Session can be null:
What should I do if the current ASP.NET session is null?
I personally often ran into this issue when I was using async requests with completion callback. In these callbacks I wanted to set something in the session and it was null.

I also had same problem,
I was toggling between debugging two different sites on localhost and there were two cookies for the session ID.
I deleted the cookies via Chrome's developer tools [Press F12 in Browser]->Application->Storage->Cookies

Related

Session is null in AcquireRequestState when loading virtual directory name in browser, but not null when loading Default.aspx

I have an ASP.NET 4.0 WebForms application. I need to access HttpContext.Current.Session and set a value in the AcquireRequestState event (or an event after it) in Global.asax, and I've found a peculiar behavior.
Let's say I have a virtual directory in IIS (version 7 in my case) called Foo. In that I have Default.aspx as the home page. A sample Global.asax file is below:
<%# Application Language="C#" %>
<script runat="server">
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext.Current.Session["key"] = "value";
}
</script>
When I visit http://localhost/Foo/Default.aspx in my browser, it works just fine. When I visit http://localhost/Foo/ I get a NullReferenceException where I set the value on the session. The only change is the URL in the browser. They end up hitting the same page, but the framework behaves differently based on whether or not the URL contains just a folder name, or if it contains an aspx file.
Checking if (HttpContext.Current.Session != null) is not an option for me, because I need to set a value on the session with every request, which is non negotiable.
Is there a config setting in IIS that I'm missing, or is this a bug/forgotten feature?
An answer for another question hinted at the fact IIS does not load the session for every kind of request, for example style sheets don't need a session. Maybe this behavior is happening because IIS can't tell ahead of time if that folder name will result in executing an aspx file or if it will deliver a static HTML file?
Update: I even tried re-ordering the default documents that IIS looks for so that "default.aspx" was at the top of the list, e.g.
default.aspx
Default.asp
Default.htm
...
And I am still getting the same problem.
Update:
The event handler is only getting fired once because it is resulting in a NullReferenceException. I've done some additional reading and I know ASP.NET triggers these events for every request, even for CSS or JavaScript files. Additionally, the session object is not loaded for static files because there is not code that accesses the session, thus no need to load the object. Even so, the very first request is the request for the web page, which will need the session, and the session is null.
#DmytroShevchenko asked:
First add a guard check if (HttpContext.Current.Session != null) so that there is no NullReferenceException thrown. Then try to see, maybe the event will be fired a second time, with a session available.
Modified code:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
I set a break point at the if statement. I saw this event fire 4 times:
session is null
session is null
session not null
session is null
When continuing to step through the code each time, only when it started executing Default.aspx and its code-behind did I have a session available. I actually had the web page open in Firefox and was monitoring the network requests. The first request was for http://localhost/Foo/.
Next I set a breakpoint in Application_BeginRequest as well and got the following events:
BeginRequest
AcquireRequestState
BeginRequest
AcquireRequestState
BeginRequest
AcquireRequestState (session is not null)
Execute Default.aspx (/Foo returns a response to the browser)
BeginRequest
AcquireRequestState (session is null again)
At #9 the AJAX request in the browser to http://localhost:54859/8fad4e71e57a4caebe1c6ed7af6f583a/arterySignalR/poll?transport=longPolling&connectionToken=...&messageId=...&requestUrl=http%3A%2F%2Flocalhost%2FFoo%2F&browserName=Firefox&userAgent=Mozilla%2F5.0+(Windows+NT+6.1%3B+WOW64%3B+rv%3A41.0)+Gecko%2F20100101+Firefox%2F41.0&tid=4&_=1445346977956 is hanging waiting for a response.
I found a discussion about the differences between serving a page by its explicit URL and serving a default document.
With MVC and WebAPI, a new HttpModule was introduced: ExtensionlessUrlHandler. I believe that your event firing multiple times (and only once with session being available) may be caused by this module or other (re)routing logic of ASP.NET that actually redirects ASP.NET to handle Default.aspx.
Also, as you yourself mentioned, these events can be triggered for static file requests.
The bottom line is, you should not rely on session being available every time your event is fired. But it is safe to assume that you can access session at least once when serving an ASP.NET page. Hence, this is how your code should look like:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
What is happening is that certain events that occur prior to transferring the request to the page, trigger this event. Similarly, this event can be raised by other than ASPX pages. I think you need to do a few things:
set AutoEventWireUp to false in your page's code (in default.aspx). It seems odd and unrelated, but apparently this can resolve your issue.
check for null. Really. Because from all events, you are only interested in those events that originated from an ASPX page (or similar) that actually have a session state. Since every true request from a user always creates a session, you can simply filter for these without worrying that you miss certain events. As you have seen, at every cycle, there is always at least one event hit that has a set Session.
use PostAcquireRequestState, it is the more natural thing to use (or use PreRequestHandlerExecute), because on that event, all state is guaranteed to be set and filled.
I think your request url is not contain ".aspx", right?
The IIS7+ version has the config whitch will not use the "SessionStateModule" when it think the request handler is not managedHandler
So the solution is easy
Find your web.config, then add the property
<modules runAllManagedModulesForAllRequests="true">
....
</modules>
runAllManagedModulesForAllRequests="true" tell asp.net use all modules anyway
hope helpfull
When the resource has compilation error then the session will be null even in Application_PostAcquireRequestState

Get users current page when session times out

Lots and lots of examples out there as to how to set and redirect when the session times out. But nothing that I could find for this situation.
A typical situation where a timeout control monitors the session timeout and displays a window warning the user of that when there is 1 minute left. When the session times out, the user is redirected to a page (sessionexpired.aspx) that clears the session and displays information informing the user that they are required to login again.
I would like to log the page the user was on when the session actually timed out and do that in the code behind of the sessionexpired.aspx page.
Any help would be very welcome!
Try looking at the Referer from the current Request object. It's usually found using this:
Request.UrlReferrer
I hope this helps.
You can use one of these code examples to get the current page the user is on:
// Returns something like "http://www.example.com/myUrl/MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsoluteUri;
// Returns something like "/myUrl/MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsolutePath;
// Returns something like "MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsolutePath.Substring(url.LastIndexOf('/') + 1);
So wherever your code is to log you out when your session expires (probably in your master page), just add one of these lines.
Once you have it, you can add it as a query string parameter to your login page or you can save it in a database.

Losing session data in ASP.NET

I moved an ASP.NET site running on a server with .NET 1.1 to another server running with .NET 2.0.
In one of the pages I have the following code to detect an expired session:
protected void Page_Init(object sender, System.EventArgs e) {
if ( Session["XBCPEmail"] == null ) {
Response.Redirect("signin.aspx?expired=yes");
return;
}
}
(Session["XBCPEmail"] == null) is resolving as true (as if the session had expired) in one unexpected case, after clicking one of the buttons of the page. It happens with only one of the buttons. Just like other buttons in the same page, the button event handler ends with this code redirecting to the same page:
Response.Redirect("cpanel.aspx");
I checked and at the time of Response.Redirect("cpanel.aspx"); the value of (string)Session["XBCPEmail"] is a valid string, so I'm not sure what can happen between the Response.Redirect and the Page_Init that could be making the Session["XBCPEmail"] become null.
Which could make a Session variable in .NET 2.0 become null? This code does not have that issue in 1.1 and, even in 2.0, it only affects one button on the page.
UPDATE: The issue only occurs if the button event handler calls an external .exe program, with the code below. If this code is commented out, the Session variable is not null. How can the creation of an external process to run a command line program have any impact on if a Session variable is null or not?
private string CallBridge3(string task, string arg1, string arg2, string arg3) {
Process process = new Process();
process.StartInfo.FileName = MapPath("bridgefcp.exe");
process.StartInfo.Arguments = "-" + task + " \"" + arg1 + "\" \"" + arg2 + "\" \"" + arg3 + "\"";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return output;
}
UPDATE 2: The problem has vanished after installing .NET 4.5 on the Windows 2008 R2 with IIS 7.5 machine, instead of using the one that came by default, which was .NET 2.0.
By default Response.Redirect terminates thread execution and there might be a race conditions in setting session variables. It is described in article Don't redirect after setting a Session variable (or do it right), so try to use another, less violent version:
Response.Redirect("cpanel.aspx", false);
Check your web.config, maybe you have this tag
<httpCookies requireSSL="true" />
If it so, remove it.
You need to update web.config as mention below :
<httpCookies requireSSL="false" />
I was facing the same issue and tried every option mentioned in the above answers.
Finally found that the issue was that we had marked session cookie as secure in our project but were running it with http
If the server has not been setup for SSL and you try to mark the cookie secure, a new session will be generated for each request.
So finally enabling back https fixed it for me.
I believe your session in the web.config is being reset (getting a new SessionID for each postback)
You could try to debug this by putting the SessionID somewhere on the page (for testing) with
HttpContext.Current.Session.SessionID
This did happen on one of my websites and all i had to do was go into IIS and resave the SessionState Panel
Just go to your web.config file and edit your sessionstate tag. Set requiressl to false from true.
I encountered this problem when setting the Session variable before a redirect. I had enableSessionState="ReadOnly" in Web.config. It happens because the session does not exists and the redirect happens before the client can set the session cookie.
My solution was to set a dummy Session variable in the previous page load (login page in my case).
protected void Page_Load(object sender, EventArgs e)
{
// Put this in master page or login page
Session["createSession"] = true; /* ensure there's a cookie for session */
}
<httpCookies requireSSL="false" />
Removing this from the local web.config worked for me. The issue was only happening when running the app locally.
Removed the setting from web.config
Added it to the web.staging.config and web.production.config
For MVC, make sure the web.config has below configuration.
<httpCookies httpOnlyCookies="true" requireSSL="false" />
in <system.web> section

ASP.NET sessionID will not update

I click on refresh button which should restart session:
protected void btnRefresh_Click(object sender, EventArgs e)
{
HttpContext.Current.Session.Abandon();
HttpCookie mycookie = new HttpCookie("ASP.NET_SessionId");
mycookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(mycookie);
LblSessionID.Text = HttpContext.Current.Session.SessionID+
" test btnRefresh_Click";
LblIsNewSession.Text = Session.IsNewSession.ToString();
}
But when the button is clicked, the SessionID value in LblSessionID still displays the old value but another label LblIsNewSession will show it as true for IsNewSession. The LblSessionID will then reflect the actual SessionID value when I use asp.net control (like dropdown) that has autopostback="true" and from there SessionID sticks around.
I do use global.asax
Any idea why LblSessionID isn't behaving as it should and is waiting for next postback to start reflecting actual value?
When I launch the web application, the problem is the same - LblSessionID show different value and then change after first postback and stays the same from there.
That's the way it works - If you Abandon the session it won't reflect that until the next Request. It makes sense if you think about it...
Say you have a user that accesses your site and gets a Session ID of 123 (not reflective of an actual value, I know). When you click your button to get a new Session ID, the user's request is from the old Session, and that is the value that is reflected during that Request. Once the session is reset (or abandoned or whatever), the user gets a new Session ID of 321 and subsequent Request's will then reflect that new session ID.
SessionId is not reliable unless you actually store something (anything) in the session.
try
Session.RemoveAll();
Session.Clear();
It is not your code, it is a documented behavior:
"The Abandon method sets a flag in the session state object that indicates that the session state should be abandoned. The flag is examined at the end of the page request. Therefore, the user can still use session objects after you call the Abandon method. As soon as the page processing is completed, the session is removed."
(source: http://support.microsoft.com/kb/899918)
The Abandon() method flags the session collection for clearing at the end of the request, it does not actually clear it immediately.
You can either call the RemoveAll() or Clear() methods for instant deletion of the objects, or issue a Response.Redirect call to the page itself and re-test for the existence of the data.

How to Kill A Session or Session ID (ASP.NET/C#)

How can I destroy a session (Session["Name"]) when the user clicks the logout button?
I'm looking through the ASP.NET API Reference on MSDN and it doesn't seem to have much information. It seems rather limited. But I cannot find any other pages for ASP.NET Classes etc.
I have tried:
Session.Abandon(); and
Session.Contents.Remove("Name"); neither of them work. ( I found these in a forum from a Google search)
The Abandon method should work (MSDN):
Session.Abandon();
If you want to remove a specific item from the session use (MSDN):
Session.Remove("YourItem");
EDIT: If you just want to clear a value you can do:
Session["YourItem"] = null;
If you want to clear all keys do:
Session.Clear();
If none of these are working for you then something fishy is going on. I would check to see where you are assigning the value and verify that it is not getting reassigned after you clear the value.
Simple check do:
Session["YourKey"] = "Test"; // creates the key
Session.Remove("YourKey"); // removes the key
bool gone = (Session["YourKey"] == null); // tests that the remove worked
It is also a good idea to instruct the client browser to clear session id cookie value.
Session.Clear();
Session.Abandon();
Response.Cookies["ASP.NET_SessionId"].Value = string.Empty;
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-10);
Session.Abandon()
This marks the session as Abandoned, but the session won't actually be Abandoned at that moment, the request has to complete first.
From what I tested:
Session.Abandon(); // Does nothing
Session.Clear(); // Removes the data contained in the session
Example:
001: Session["test"] = "test";
002: Session.Abandon();
003: Print(Session["test"]); // Outputs: "test"
Session.Abandon does only set a boolean flag in the session-object to true. The calling web-server may react to that or not, but there is NO immediate action caused by ASP.
(I checked that myself with the .net-Reflector)
In fact, you can continue working with the old session, by hitting the browser's back button once, and continue browsing across the website normally.
So, to conclude this: Use Session.Clear() and save frustration.
Remark: I've tested this behaviour on the ASP.net development server. The actual IIS may behave differently.
Session.Abandon() this will destroy the data.
Note, this won't necessarily truly remove the session token from a user, and that same session token at a later point might get picked up and created as a new session with the same id because it's deemed to be fair game to be used.
You kill a session like this:
Session.Abandon()
If, however, you just want to empty the session, use:
Session.Clear()
Session.Abandon()
is what you should use. the thing is behind the scenes asp.net will destroy the session but immediately give the user a brand new session on the next page request. So if you're checking to see if the session is gone right after calling abandon it will look like it didn't work.
Session["YourItem"] = "";
Works great in .net razor web pages.
Session.Abandon(); did not work for me either.
The way I had to write it to get it to work was like this. Might work for you too.
HttpContext.Current.Session.Abandon();

Categories