I have this piece of code:
var thisUser = Session["user"];
if (thisUser == null)
{
LogFile.Log("Logging out");
Response.Write("xp");
}
I am trying to track down why sometimes when I play with the system for a few minutes and suddenly the user session variable gets null.
It happens randomly in different scenarios.
I do not set the Session["user"] to null at any point.
Session timeout is set to 20 minutes.
I do not call Session.Clear() at any point.
Any ideas\thoughts\things I should look at as to why is it may happening?
I am using Firefox if that to any help.
The system is built with asp.net.
For more info please ask.
are you calling the same host? if the base URL is different the server will treat this as different users. for example:
http://localhost/path/to/resource and http://localhost:80/path/to/resource
both point to the same resource, but the requests are different and the session cookie will be different, or not present.
An easy way to test this is to launch your browser's developer toolbar and monitor the network traffic. compare the URLs to make sure they are the same base path and the same session cookie is passed in the request.
First of all this looks like C# and ASP.NET, not classic ASP. Now if you never clear the session yourself and the server (or the app pool) is never restarted, then the only way to lose the session is to clear the browser's cookies.
Editing the web.config will recycle the app pool, which clears the session info.
Related
I have a single-page, .NET 4.7.1 MVC application. My Page_Load() for Default.aspx.cs sets session variables and, when my breakpoint at the last line of Page_Load() is hit, the session object is stored correctly. However, when I click a link and hit my breakpoint on the first line of Page_Load() for the second call, HttpContext.Current.Session has no session variables set. Also, HttpContext.Current.Session.SessionID changes after the first call and then remains the same. Subsequent calls work correctly but the first one after an app pool recycle is always empty.
I have no httpCookies entry in the web.config and I'm always accessing via HTTPS. The app is running in an azure app service and I'm using OpenID Connect for authentication. Under what circumstances are variables removed from HttpContext.Current.Session before timing out?
UPDATE: I've added some diagnostic logging and sometimes SessionID changes without dropping the actual session data. I don't know how this can be but thought I'd record it. Also, it appears that my logging of the session ID has fixed the problem. I've seen others mention that the session is not preserved until it's been accessed (which is happening) but (without having searched exhaustively) I suspect all the session reading and writing in the first call is taking place in other assemblies and therefore perhaps not being 'counted' as reason to preserve the session? This seems very hokey but is my only guess for now. I'm still confused why it would have started breaking now.
I have to implement session handling across multiple users, and multiple browsers. Each user has a unique token which I save in HttpContext.Current.Session variable inside the Session__Start() in Global.asax.cs method. It works perfectly fine for a single session. However, when I fire the request from two browsers, then while browsing through various pages, sometimes the method Session_Start() automatically gets called for the second session and it resets the session variable, resulting in a null value.
How should I handle this scenario?
Edit 1:
What are the scenarios where the session may time out? Eg: switching between HTTPGet/HttpPost, or making Ajax calls?
I also read this link:
Does Session timeout reset on every request
Is this something which I should be keeping in mind? My code has 2 GET and 1 POST request, and the session variable becomes NULL in the POST method for the second browser session.
I figured out the reason. The sessionState mode in web.config file was set to "InProc", whereas it should be set as "StateServer". When I made the necessary change, then it worked like a charm.
ASP.net state service should also be started from services.msc for this to work.
I am using session to do two things:
Keep track of which css file to load for a particular company.
Keep track of the Company Id Guid that tracks what company we are in.
I am seeing that this is coming in as null sometimes but I'm not getting a consistent problem to track down. I have no doubt this is probably something in my code that I need to track down but this bring me up to my questions about session...
Am I relying on Session to much to pass information between screens?
Is it consistent?
What could be clearing it between page loads?
Is session easily cleared by the user?
Should I be using something else more reliable?
I am worried that I will move this to live usage and have all kinds of problems.
I'm simply doing this:
Session["Css"] = css;
and reading it the same way:
css = Session["Css"]
UPDATE
The session I am using:
HttpSessionStateBase Controller Session
There are a few types of Session State. InProc, StateServer, and SqlServer. I believe the default is InProc. You can read more about this on MSDN here and here.
Each of these will obey the timeout value for sessionState defined in your web.config file. For a single server setup (which is what I typically do) I usually have my sessionState setup as follows:
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
timeout="2880" />
This is the same default timeout as Forms Auth, so my sessions will stick around as long as my users auth cookie/session. This will require you to set the start up on the ASP.NET State Server to Automatic. Below is my high-level pass at explaining the types and their potential drawbacks.
InProc
This will be reset everytime the application pool recycles the worker process for the web app. I believe this is what is happening to you, and this is why your session variables are null at what appear to be random times.
StateServer
This will persist state across apppool recycles, but requires that you enable the ASP.NET State Server Service, and change it's start up type to Automatic.
You can run into issues if you have a web farm or multiple web servers handling the website, unless you run a dedicated state server.
This requires that variables stored in session variables are [Serializable].
SQLServer
This will persist session variables to a SQL database, and is is generally the best approach for a web farm situation.
This requires that variables stored in session variables are [Serializable].
Could you not be writing your method to GetCss() something along these lines?
GetCss() {
var css = (CastToYourTypeHere)Session["css"];
if(css == null) {
//do whatever you'd normally do here to set the css,
//e.g. get the users guid and find their company css, and set css equal to it
css = myHypotheticalGetCssBasedOnTheUserFunction();
}
return css;
}
That way you're kind of covering all bases in that, you can happily use Session, if it it's lost for whatever reason you're just re-running your initial 'getCssForThisUser' type code.
IMO, session isn't a bad way to hold this kind of data for each user between pages in the type of example you've described.
Hi,
The login method in my ASP.NET MVC page looks something like this :
Check ModelState
Check Username and password
user = accountModel.GetUser(model.UserName);
this.HttpContext.Session[Biss.Extensions.SessionKey.userContext.ToString()] = new UserContext() { SiteRole = (SiteRoles)user.RoleId, Id = user.Id };
FormsAuthentication.SetAuthCookie(model.UserName, createPersistentCookie);
During development Im rebuilding, restarting the solution alot of times and I have notice the following :
Start website
Login(with method above)
Rebuild soultion
Restart website
Now the User.Identity.Name will still be set but the
HttpContext.Session[Biss.Extensions.SessionKey.userContext.ToString()]
is null? I supose that the website is restarting when doing a rebuild/restart but how can the User.Identity.Name still be set? How could I handle this?
BestRegards
Since you are restarting the AppDomain the session is deleted as it is stored in memory. Think of it that the exactly same thing might happen in your production server. Under certain circumstances IIS could simply restart the application pool: for example after some inactivity or memory/CPU threshold is reached. To avoid loosing your session data you could use an out-of-process session storage so that it doesn't stay in memory. Look at the following article for the different possibilities: http://msdn.microsoft.com/en-us/library/ms972429.aspx
As you restarting the web site, you flush out you Session. The state of session is simply gone.
I would recommend to get rid of using Session for such simple scenario as user login. My general answer almost everywhere - do use session if you have very serious reason for that.
You can keep the information about user in database and read it than you actually need.
I'm pretty basic with .net
But basically I've been told that to have session stickiness for my website in the environment it is to be deployed means I have to get session from the cookie ASP.NET_SessionId
But what does this mean/how do I use this?
And where I am using my existing session code e.g. Session.Add("Something", something) do I now need to change this?
This is automated for you
You don't have to manually read cookies yourself. Asp.net does it for you. So whenever you access Session dictionary your session will already be preserved if it existed from your previous request(s). If there is none (or expired) it will also be automatically created so adding items to it will make it work without a problem.
So basically instead of accessing Session identifier from a cookies and do whatever with it (as you won't be able to access intrinsic session store), just use Session:
Session["SomeKey"] = myVar;
// or
Session.Add("SomeKey", myVar);
and for reading
var o = Session["SomeKey"];
Are cookies mandatory?
Basically Asp.net supports other means of session ID storage apart from cookies. You can enable cookieless session if you wanted to (a setting in web.config file). Session identifier will be added to your URL like:
http://www.example.com/(S(lit3py55t21z5v55vlm25s55))/orderform.aspx
Read more about it here on MSDN.
What's the default?
By default session identifier is preserved in cookies. That means that you don't have to change anything in web.config. But if you'd like to use other means you'd have to set that in web.config (check the same upper link as before).
Typically the way that I use session variables in ASP.NET is like this
// set
Session["SessionVariableName"] = localVariable;
// get
localVariable = Session["SessionVariableName"] as LocalType; // then check nulls
The issue with any sessions is that if you don't go out of your way to change it, the default stores sessions in-proc so every time IIS recycles a worker process your session is lost. This can be easily fixed by using the built-in ASP.NET State Service. A quick search turned up this article on using it.
You can get a reference to the current session in multiple ways but the most easy way is just use the session property on the page.
See:
http://msdn.microsoft.com/en-us/library/system.web.ui.page.session.aspx
Session stickiness is not a feature of ASP.net, but rather of a load balancer that may sit in front of it. If you are using InProc sessions, then the session data is stored in the server's memory. With "sticky" sessions, the load balancer will send all requests from the same source (based on IP usually) to the same server to ensure that the session always exists.
This isn't the most scalable way to handle a web farm scenario. Microsoft introduced two other mechanisms, StateServer and SqlServer which serve to send the session data to a single location for all web front ends.
You likely just need to make sure you don't have cookieless set to true in your configuration.
Regardless of how this is all configured, you will always retrieve your session data the same way - ASP.NET abstracts the details away.
// Set
Session["mySession"] = "Hello World";
// Get
var s = Session["mySession"];