I've got a really really strange ASP.net intermittent session persistence problem. First some facts:
Environment:
F5 Load Balancer with sticky sessions enabled:
Web Servers: 2 *
Windows Server 2008 R2,
.net Framework Version: 2.0.50727, IIS7,
Database Server: SQL Server 2008 R2
Session Protocol: ASP.net InProc sessions, timeout set to 20mins, cookieless=false
CMS: Ektron CMS
400.net
Ok on with the problem.
We have some custom VB.net session values which get set in our website for a shopping cart. from time to time SOME of these variables seem to lose persistence. I say some because the main session remains persistent. I think the main culprit is this fellow:
Shared Sub New()
' If the cart is not in the session, create one and put it there
' Otherwise, get it from the session
If HttpContext.Current.Session("ASPNETShoppingCart") Is Nothing Then
Instance = New ShoppingCart()
Instance.Items = New List(Of CartItem)
HttpContext.Current.Session("ASPNETShoppingCart") = Instance
Else
Instance = CType(HttpContext.Current.Session("ASPNETShoppingCart"), ShoppingCart)
End If
End Sub
Even when this session object remains persistent, it doesn't show up when I run a trace:
e.g.
my other sessions variables like Session("userId") show up in a trace while I NEVER see a value for Session("ASPNETShoppingCart") - which I thought was strange - perhaps this is because it is an object as opposed to a string?
I've ruled out issues with the load balancer by bypassing it directly and calling the code directly on the server.
I know the full session is not being destroyed when the issue occurs because I'm still logged in and other session values appear on screen - but my shopping cart values do not.
Has anyone any idea as to what might cause something like this? Is there any way of protecting a session variable or at least being notified if it changes state so I can trace what's causing this?
Indeed, it is strange that "some" variables get lost and some don't.
Maybe you have some sort of "fallback" mechanism that recreates the "UserID" (from an authentication cookie, for example) and the same doesn't happen for other objects.
In general, I'd avoid using InProc session state at all costs because whenever the asp.net Worker process get's recycled -and this can happen at any time-, everything in the Session will be lost. Since you use sticky sessions, my suggestion is that you switch to OutOfProcess mode using a local StateServer. You can read more here.It's very simple to configure; just a change in the Web.config and making sure that the ASP.NET State service is started on the server.
The only caveat is that all your objects need to be Serializable but if you are not storing something exotic in Session, all you need to do is decorate your objects with the [Serializable] attribute.
Related
I have a simple scenario. in one page of asp.net, I store a some values in session like
session("var") = "some string"
or
session("var1") = object of generic list of string
and then use response.redirect to goto another page.
on other page it shows things fine, but when we press a button to do an action on it, session gets null.
Remember, it doesn't always happen. Just sometimes it does so and other times it works fine. We do this practice a lot to move some values from page to page (by storing them into session and goto other page). We have very big application and all works fine, but from some days, have been having this issue on some sites with some users. Once again, it doesn't always happen. 99% it works fine but few times, we have this issue where session variable is no longer available.
Is there any way to know what is going wrong and where? We do store some other variables in the session as well, they seems fine at that time. only some of the session variables lose their values.
From my research, it seems people blames on the IIS worker process restart or Application Pool recycle. But I believe in such case all the session variables in the application must be voided, not selected few. Right?
also, is there any way to know in code if the pool or worker process was restarted?
thanks
Sameers
Perhaps you're passing domain boundaries. Session is identified by a client cookie, which are usually stored on a per-domain basis. So, for example, a redirect from www.whatever.com to client.whatever.com will cause you to lose the session ID, which will appear to you as "voiding the session". So, be careful about sub-domains too. Going from whatever.com to www.whatever.com is fine, but the other way round, nope.
And yes, unless you're on a web farm IIS, restarting the worker process will kill all the sessions. Unless you store them in a database or something.
The above simplifies my situation, but highlights my dilemma -- occasionally my users are unable to access their session variables (well before the session timeout). My configuration is as follows:
Application is .NET Framework 3.5
Session State is handled by StateServer (running locally on web server)
StateServer service running on the web server is .NET Framework 4.0
There is only one web server, it is not a farm or garden situation
I have a page in the flow of control that sets a session variable to an instance of a custom user object (If I binary serialize the objects to the filesystem, their size can be between 6kb and 30kb, so not small, but not very large either). The application usually only has as many as 10 simultaneous users max. Subsequent pages in the flow of control, check that the session variable is not null. If the session variable is null, it is assumed that the session has timed out and the user is redirected to a "lost session" page. I have placed (for debugging purposes) another check on that same session object in the lost session page.
What I'm seeing in the logs is very strange -- users are being sent to the lost session page, but the object does indeed exist in the session! Is it possible that the session variable be null on PageTwo.aspx but not null on LostSession.aspx? Is it possible that PageTwo.aspx is run too soon -- meaning the object has not yet been fully "written" to the Session StateServer?
Any ideas on how I can debug this further?
Because the user object exists in LostSession it should also exist in PageTwo. Since you use redirect there should be no problems with data being accessed too soon.
You could try to set a checkpoint on in PageTwo on the line where the user object is being assigned and look into the session object manually. Comparing it with PageOne and LostSession might give you a clue what causes your issue.
It is possible that the key contains a typo and thus the user object is set to null, because the key referenced has no object in the session.
I have an asp.net web app which uses state server to store its sessions. When we change a type of something which is stored in the session, all users with active sessions got error, beacuse the "old session" contains insrtances of "old type".
I thought that the simplest way to overcome this problem would be to restart the state server, therefor get rid of all sessions. However, this was proffed to be a naive approach. Sessions seems to be still active (users with session old cookie are still capable of working). Is there some other way to force the session state server throw away all sessions, so that old users will be assigned new session? It is ok if they would be forced to authenticate again.
Or is there some other (better) way of abandoning all sessions? Ideally not programmaticaly, but something our admin could do?
Programmatical approach woudl be maybe calling Session.RemoveAll in Application_End would solve the issue, bu is this standard approach?
Where are session stored in state server if not in memory (which should cease to exist on restart)?
I have found two SO questions which are relevant:
Clear all sessions on application start - this is rather incomplete programmatical solution
How to clear SQL session state for all users in ASP.NET - this is exactly what I would needed if I had had an sql server approach of storing of session data
Ok, So it seems so (after a bit of experimenting), that restarting of the session state server throw away all data in the session.
The users still have their session ID valid after restart though, which got me originally thinking that the session is not thrown away.
I guess that if the session id sent from a user is not assigned to some existing session, than it is reused for the new one, so user still operates with the same id. Nevertheless, the data in session are cleared.
This doesn't directly answer your question but a clean programmatic workaround could be to wrap access to Session and try to be smart and detect issues:
// example
public string SomethingWrapper
{
try
{
return (string)Session["something"];
}
catch
{
return "defaultvalue";
}
}
This should work for value objects and composite objects too. If the deserializer fails for a compound object, you get an exception and have a chance to return just anything, a default value for example. Or you can recreate the value and put it back into session container.
I've implemented a custom session state provider for Oracle in my application. It seems to run smoothly (without errors!), but I'm having trouble retrieving some Session variables when I redirect to another page. But it doesn't happen all the time.
When the Session starts, I load a User object into Session. It stays there, because when the user gets to the starting page (and is authenticated), the app still recognizes him. It has no problem retrieving the User object from Session.
But if I pass a value into Session on one of my pages inside the app, then redirect to another page in order to utilize that Session variable, the new page retrieves null from the same named Session variable. Using the Visual Studio Watch window, I can actually see its value change from "100" (or whatever) to null. I don't get it.
The session provider seems to be working correctly because as I said, I'm able to persist some variables. Does someone know what the reason might be for Session to "lose" a value? Thanks.
If you are doing a response.redirect in the page, that can cause the thread to abort before the Session is written back to the database.
I'm a little confused about the life cycle of the session in ASP.NET, here is my test case.
A user logs in, I save some info to a session variable (e.g. Session["bob"]="bob") then I do an "IIS reset". The user is still logged in, but the session data is null (e.g Session["bob"].ToString() throws a NullReferenceException.
I expected the session data to still be around. Is there something I can do, other than log out the user? I expected the session data to be around as long as the user is still logged in.
Any good links so I grok what's going on, as well as any help with the actual issue is greatly appreciated. I tried to Google this, but wasn't able to frame the question in a way to get what I wanted.
The behavior you are seeing - where the Session contents do not survive an IIS reset event - is due to where the Session values are stored. By default these values are stored within the memory of the ASP.NET "Worker Process", which is the program which runs your ASP.NET web site.
When you perform an "IIS reset" you shut down the entire IIS server, including the ASP.NET Worker Process. This means that the contents of the Session are removed from memory. Your user still appears to be logged in because that is controlled by the cookie stored in their browser. If the cookie is still valid, the login is.
If you wish your Session state to survive an IIS reset (or anything else which causes the ASP.NET worker process to restart) you'll need to store your Session objects in another place. This is fully supported by ASP.NET by using different Session storage "Modes". Read about those in the MSDN article "Session-State Modes".
For a general overview of the Session, check out the "ASP.NET Session State Overview" article on MSDN.
yah its right but some time its happen then session no remove properly at that time
you have to check session like
If Session("username") = nothing then
Response.redirect("~/default.aspx")
End if