I am currently using Session["Name"]="a name" in my controller which work. But when I try refresh the page the session gets empty. Anyone know why?
My config file got:
sessionState mode="InProc" customProvider="DefaultSessionProvider">
with provider to connectionstring
First try adding the following attribute to your sessionState element (in web.config):
timeout="10080"
(that's 1 week, in minutes).
Your session should then survive for at least several minutes. Since you're storing it In Proccess (mode="InProc"), when your IIS App Pool's worker process recycles all the session data stored in that process will be lost.
If you need to store session data for longer periods of time than your worker process will be alive (or if you want to use multiple worker processes or even multiple web servers), you'll need to store your session out-of-process (e.g. in SQL, on a network share, or in AppFabric).
Related
I am developing an MVC project with the web API. When the user logs in, I am sending a token to the web service. I keep this token in the Session object on the MVC side. If this session is null, I want to log in again from the user. But sometimes this session object is deleted by itself. What could be the reason for this?
Session has a timeout period of 20 minutes. It could mean that your user did not post anything back to the server within these 20 minutes.
Another problem that might cause a session timeout is if you change something in web.config or some other file through Visual Studio for example. This will trigger the compilation process in the background and will reset your session.
The default session, out of the box one, is InProc session. This means that your session is running in the same process as your web application.
If you want to preserve the session while still being able to update the web application, you need to use either Out of process or SQL Server as a session store. (Note that these session states are not really meant for the scenario where you will be updating things locally, but rather when in production and/or if you have a web farm, but nothing prevents you from using them locally.)
StateServer (out of process)
This session mode will use a service call ASP.NET State Service. This service is set to manual. You will first need to open services (click on Start -> Run -> services.msc). Find the above mentioned service, double click and change the startup to Automatic, then Start.
In your web.config you will need to update or add (if it does not exist) the following key under <system.web>:
<sessionState mode="StateServer"
stateConnectionString="tcpip=YourComputerNameGoesHere:42424"
cookieless="false"
timeout="20"/>
Update the timeout value to whatever it suits you.
SQLServer state
SQL Server state allows you to store your sessions in a designated database on your server. One thing you must remember is that this is the slowest option of all as it has to travel from server to server (in your case it might be the same server, but keep this in mind if you separate web application and sql server)
To configure SQLServer state you must perform a couple of extra steps. First, add the configuration to the web.config:
<sessionState mode="SQLServer"
sqlConnectionString="Integrated Security=SSPI;data source=MySqlServerForSessions;" />
(I cannot recall now whether you can change the name of the database, but for now work with the default values.)
The next step is to run aspnet_regsql command from your command prompt. This command should be in your C:\Windows\Microsoft.NET\Framework\vX.Y.ZZZZ (where X.Y.ZZZZ is the version of .NET Framework. Try with the highest one that you have):
aspnet_regsql.exe -S MySqlServerForSessions -E -ssadd -sstype p
This will create a new database where the sessions will be stored. If you have SQLExpress you might run into an issue when running this command. For that you need to run:
EXECUTE sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
EXECUTE sp_configure 'Agent XPs', 1
RECONFIGURE WITH OVERRIDE
GO
EXECUTE sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
GO
This should help you work with the sessions. One thing to remember is that in global.asax you cannot use Session_End event when you use StateServer or SQLServer. This event triggers only for InProc session state.
For more information have a look at these two links:
ASP.NET Session State Overview
Session-State Modes
Handling Session and Authentication Timeouts in ASP.NET MVC
Trying to hunt this down all day.
I can get sessions to work if I used a "StateSever". Holds a session from controller to controller and on refresh. If I use "InProc" the session lives from controller to controller but on refresh it dies [null]. The timeout should not be an issue because I run it immediately.
Any help on this is appreciated. I really don't want to use stateserver...at least until I understand why this is happening.
Web config
<!--<sessionState cookieless="UseCookies" timeout="1440" mode="InProc"/>-->
<sessionState cookieless="UseCookies" timeout="1440" mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424"/>
Controllers
public ActionResult Login()
{
System.Web.HttpContext.Current.Session["SessionVal"] = "Test";
return View();
}
public ActionResult LoginSuccess()
{
return View();
}
Views
#{
Layout = "";
}
<h2>Login</h2>
Go Here
2nd view
#{
Layout = null;
}
Session: #Session["SessionVal"]
I disabled the session state in web config. I put a DateTime in the
session The first time I run the project it displays the session. I
hit F5 and it remakes the session. I continue to hit F5 and it holds.
I enabled stateserver and do the same process but it never remakes the
session on the first refresh.
By default, sessionState is InProc mode. InProc means Session are stored in memory on the Web server. If you debug in Visual Studio, it will be your local computer's memory.
Since memory is not a persistent storage, the sessionState is clearned up by Garbage Collector as soon as your application is stopped.
The bottom line is it is by design and there is nothing you can do about it.
If you want to persistent the sessionState even after application is stopped, you need to use StateServer or SQLServer.
InProc literally means in process. It lives and dies with the process it's running on. IIS Express is a throwaway server - quite literally. Visual Studio starts and stops IIS Express all the time for a number of different reasons. For example, every time you stop debugging, by default, IIS Express is killed (though that can be changed on a project by project basis).
Long and short, InProc sessions are unstable even with real IIS on a server. They're that much more so on IIS Express on a local dev box. If you need or want stability of session data between requests, then you need to use something other than InProc.
My IIS session occasionally loses all data stored in it, it usually takes about 3-5 minutes, but definately less then the session timeout set in the web.config. The problem is not reproducible reliably, when it happens, accoring to the logs the AppPool is not recycled and the Session ID remains the same, it just loses all data. Any suggestions on how to debug this?
So far I tried to overwrite the session provider and stored the session data into a static variable, we checked all relevant timeouts and we stored a dummy value in the session, that is lost as well
A number of things can cause session state to mysteriously disappear.
Your sessionState timeout has expired
You update your web.config or other file type that causes your AppDomain to recycle
Your AppPool in IIS recycles
You update your site with a lot of files, and ASP.NET proactively destroys your AppDomain to recompile and preserve memory.
If you are using IIS 7 or 7.5, here are a few things to look for:
By default, IIS sets AppPools to turn themselves off after a period of inactivity.
By default, IIS sets AppPools to recycle every 1740 minutes (obviously depending on your root configuration, but that's the default)
In IIS, check out the "Advanced Settings" of your AppPool. In there is a property called "Idle Time-out". Set that to zero or to a higher number than the default (20).
In IIS, check the "Recycling" settings of your AppPool. Here you can enable or disable your AppPool from recycling. The 2nd page of the wizard is a way to log to the Event Log each type of AppPool shut down.
If you are using IIS 6, the same settings apply (for the most part but with different ways of getting to them), however getting them to log the recycles is more of a pain. Here is a link to a way to get IIS 6 to log AppPool recycle events:
(APEX 4.1.1.00.23)
I have two applications A and B that share the same session (because they use the same session cookie), and each has Maximum Session Idle Time set to the same value N. Having established a session and visited both applications, if I then spend more than N seconds working in application A (doing lots of page loads so not timing out), if I then navigate to application B it immediately times out and sends me to its login page.
I tried also calling APEX_UTIL.SET_SESSION_MAX_IDLE_SECONDS(N) in both applications, with p_scopr defaulting to 'SESSION', noting that the API docs say
This would be the most common use case when multiple Application
Express applications use a common authentication scheme and are
designed to operate as a suite in a common session.
However the same thing happens.
I want the timeout to apply to the session as a whole, not to each application independently. Is this not what the above is supposed to achieve, or am I doing something wrong?
I got the answer to this from Christian Neumueller on the Oracle APEX forum:
... it's no issue anymore in 4.2. Looking at the 4.1.1
code, it seems that the problem is how we stored the last access time.
While the APEX_UTIL call with SESSION scope would set the idle timeout
for both apps, we maintained a timer (FSP_LAST_REQUEST_TIME) for each
app. Working in TIMTEST1 only updated the timer for TIMTEST1, not for
TIMTEST2. After working with one app and switching back to the other
app, Apex sees the stale timer and decides that the session expired.
This is clearly a bug. The bad news is that a backport is not
feasible, because so much has changed in session state management.
If you are running a Rails 3 app with multiple web dynos on Heroku,
Every time you hit the app, do you typically connect with a different web dyno?
Can sessions work across different web dynos?
Does it work for different Rails session stores (ActionDispatch::Session::CookieStore,
ActiveRecord::SessionStore, and ActionDispatch::Session::CacheStore)
In short yes - sessions will work across multiple web dynos.
Sessions work across web dynos - because Rail's design of session support allows it to. If anything, the web dyno model is exactly how Rail's was intended to be scaled horizontally.
1. Every time you hit the app, do you typically connect with a different web dyno?
Based on heroku documentation:
The routing mesh is responsible for determining the location of your application’s web dynos within the dyno manifold and forwarding the HTTP request to one of these dynos. Dyno selection is performed using a random selection algorithm.
So dyno selection is random... but that dyno has to have your application installed. So if you have more than one dyno, then you may end up connecting to a different dyno (which is important as this facilitates load balancing and high availability)
2. Can sessions work across different web dynos?
Yes. Most web stacks support sessions by doing the following:
Assigning a session id - which is a unique id, and it is usually set as a session cookie so that the browser will always send the id with ANY HTTP request to the originating host
Providing storage which maps the session id to the actual session data
So by this process, sessions can be supported as every inbound HTTP request has the session ID, which is accessible by the web dyno when it handles your request.
3. Does it work for different Rails session stores (ActionDispatch::Session::CookieStore, ActiveRecord::SessionStore, and ActionDispatch::Session::CacheStore)
ActionDispatch::Session::CookieStore
Yes. The cookie store stores encrypted session data as a cookie. So your browser sends all the session data (encrypted) back to the host, which is then decrypted for use within your app.
ActiveRecord::SessionStore
Yes. The cookie store stores encrypted session data in a database table. An ID is then assigned as a cookie. So your browser sends the ID to the host, which is then used to load the session data from the database. Since all web dynos have a connection to the DB, this means it is also supported.
ActionDispatch::Session::CacheStore
Yes but you need a cache store service (eg MemCache addon). The cookie store stores encrypted session data in a cache store (memcache), which is a shared service across all web dynos. An ID is then assigned as a cookie. So your browser sends the ID to the host, which is then used to load session data from the cache store (memcache).
I do not believe Heroku makes any effort to send consecutive requests to the same web dyno. I might be wrong and they make some effort, but even if they do, it isn't likely to be anything like reliable enough to count on for session management.
However, ActionDispatch::Session::CookieStore will definitely work because the data is stored in an encrypted client-side cookie. ActiveRecord::SessionStore will work because the data is stored in the database, which is presumably shared by all web dynos. ActiveDispatch::Session::CacheStore should work if you use a MemCached server shared between all clients, or a similar shared cache.
The only thing that wouldn't work is some sort of file-based session storage on the local filesystem, and situations like multiple Heroku dynos is exactly why that type of session storage is not common in modern web applications.