ASP.NET: Session.SessionID changes between requests
Asked Answered
O

14

149

Why does the property SessionID on the Session-object in an ASP.NET-page change between requests?

I have a page like this:

...
<div>
    SessionID: <%= SessionID %>
</div>
...

And the output keeps changing every time I hit F5, independent of browser.

Overawe answered 20/5, 2010 at 13:22 Comment(0)
S
248

This is the reason

When using cookie-based session state, ASP.NET does not allocate storage for session data until the Session object is used. As a result, a new session ID is generated for each page request until the session object is accessed. If your application requires a static session ID for the entire session, you can either implement the Session_Start method in the application's Global.asax file and store data in the Session object to fix the session ID, or you can use code in another part of your application to explicitly store data in the Session object.

http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx

So basically, unless you access your session object on the backend, a new sessionId will be generated with each request

EDIT

This code must be added on the file Global.asax. It adds an entry to the Session object so you fix the session until it expires.

protected void Session_Start(Object sender, EventArgs e) 
{
    Session["init"] = 0;
}
Sentimental answered 20/5, 2010 at 13:32 Comment(14)
I did not know that, never had an issue with it but that is interesting to knowTruncated
@Cladudio could you just throw in one line of code and your answer is perfect. Interesting information coming out of an interesting question... plus one? ;)Overawe
Does this mean that a new Session is generated for each page request until the session object is accessed?Hierarchy
Interestingly enough, this fixes my issue - but the issue only manifested itself after about 6 months of using the codebase without a problem. I can't think of any reason why this would suddenly have changed - can anyone suggest a reason why the sessionid would suddenly get reset when it hadn't before?Destination
Thanks a ton for this answer. I have an implementation where I need the session ID to be constant and spent quiet a bit of time trouble shooting the issue. Thanks @ClaudioRediShererd
@ClaudioRedi,suppose i do not use session_start,and i create one session after successful login say ,Session["user"]=someid.Then what happen to Sessionid ?i am not getting this term "unless you access your session object on the backend...".Is there any article explaining this apart from the link you gave.Weathertight
@KumarHarsh: once you store any object on session, the session id will be fix. That's what I meant to say with "unless you access your session object on the backend...". Once you assign someid the session if will remain the same. Take into account that this answer is more than 4 years old, not sure if there was any modification in relation to this.Sentimental
I noticed that simply adding the Session_Start method WITH NOTHING IN IT to my Global.asax made this work. Thanks @Claudio for the tip though.Carvalho
@Moo: This was working fine for me for about 6 years until I decided to clean up my global.asax and removed methods that had nothing in their bodies, this included an empty Session_Start method. I added that method back and things are working again.Carvalho
@Carvalho I went one better - I no longer use Web Forms. Don't have any issues like this any more.Destination
Massive gotcha. Spent hours trying to figure out what the root cause of this was. Thank you very much for your answer!Eyebolt
I like @Pedro's solution of a Session_Start method with nothing in it. Anyone know if this will cause the session ID to be retained across servers in a web farm?Cookhouse
@mwardm: To retain the session ID across multiple servers you need do use an ASP.NET session service or an ASP.NET session DB.Carvalho
@Carvalho That would be poor, but not entirely unpredictable. I might have to try it out though. To be clear, I have no state to store, I just need the ID as a key (for sending to another service, say). AFAIK that just comes from the cookie (which obviously each server in a farm must be able to interpret because that's presumably what it keys any data in the session service by).Cookhouse
K
100

There is another, more insidious reason, why this may occur even when the Session object has been initialized as demonstrated by Cladudio.

In the Web.config, if there is an <httpCookies> entry that is set to requireSSL="true" but you are not actually using HTTPS: for a specific request, then the session cookie is not sent (or maybe not returned, I'm not sure which) which means that you end up with a brand new session for each request.

I found this one the hard way, spending several hours going back and forth between several commits in my source control, until I found what specific change had broken my application.

Kep answered 19/8, 2011 at 14:31 Comment(4)
I knew this but still forget it every 3 months or so and spend a couple of hours debugging..Prewitt
In my case, i was testing on localhost and the "requireSSL" in web.config was set as "true". Thanks.Afore
this was my case, and I spent way too much time trying to figure it out (had a red herring with different web.config files).Waterman
Your suggestion above is still helping in 2018. This is the most frequent scenario. Thanks!Donative
U
6

In my case I figured out that the session cookie had a domain that included www. prefix, while I was requesting page with no www..
Adding www. to the URL immediately fixed the problem. Later I changed cookie's domain to be set to .mysite.com instead of www.mysite.com.

Umeko answered 14/3, 2013 at 15:18 Comment(0)
M
5

my problem was that we had this set in web.config

<httpCookies httpOnlyCookies="true" requireSSL="true" />

this means that when debugging in non-SSL (the default), the auth cookie would not get sent back to the server. this would mean that the server would send a new auth cookie (with a new session) for every request back to the client.

the fix is to either set requiressl to false in web.config and true in web.release.config or turn on SSL while debugging:

turn on SSL

Madrepore answered 18/2, 2016 at 18:15 Comment(1)
How is this different to Neville Cook's answer from 2011?Anabantid
R
4

Using Neville's answer (deleting requireSSL = true, in web.config) and slightly modifying Joel Etherton's code, here is the code that should handle a site that runs in both SSL mode and non SSL mode, depending on the user and the page (I am jumping back into code and haven't tested it on SSL yet, but expect it should work - will be too busy later to get back to this, so here it is:

if (HttpContext.Current.Response.Cookies.Count > 0)
        {
            foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
            {
                if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
                {
                    HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
                }
            }
        }
Resign answered 20/5, 2010 at 13:22 Comment(0)
S
3

in my case it was because I was modifying session after redirecting from a gateway in an external application, so because I was using IP instead on localhost in that page url it was actually considered different website with different sessions.

In summary

pay more attention if you are debugging a hosted application on IIS instead of IIS express and mixing your machine http://Ip and http://localhost in various pages

Seidel answered 4/1, 2018 at 5:41 Comment(0)
C
2

Another possibility that causes the SessionID to change between requests, even when Session_OnStart is defined and/or a Session has been initialized, is that the URL hostname contains an invalid character (such as an underscore). I believe this is IE specific (not verified), but if your URL is, say, http://server_name/app, then IE will block all cookies and your session information will not be accessible between requests.

In fact, each request will spin up a separate session on the server, so if your page contains multiple images, script tags, etc., then each of those GET requests will result in a different session on the server.

Further information: http://support.microsoft.com/kb/316112

Chiropractic answered 22/10, 2013 at 14:3 Comment(0)
F
2

My issue was with a Microsoft MediaRoom IPTV application. It turns out that MPF MRML applications don't support cookies; changing to use cookieless sessions in the web.config solved my issue

<sessionState cookieless="true"  />

Here's a REALLY old article about it: Cookieless ASP.NET

Felipe answered 15/4, 2014 at 23:32 Comment(0)
C
2

In my case this was happening a lot in my development and test environments. After trying all of the above solutions without any success I found that I was able to fix this problem by deleting all session cookies. The web developer extension makes this very easy to do. I mostly use Firefox for testing and development, but this also happened while testing in Chrome. The fix also worked in Chrome.

I haven't had to do this yet in the production environment and have not received any reports of people not being able to log in. This also only seemed to happen after making the session cookies to be secure. It never happened in the past when they were not secure.

Update: this only started happening after we changed the session cookie to make it secure. I've determined that the exact issue was caused by there being two or more session cookies in the browser with the same path and domain. The one that was always the problem was the one that had an empty or null value. After deleting that particular cookie the issue was resolved. I've also added code in Global.asax.cs Sessin_Start method to check for this empty cookie and if so set it's expiration date to something in the past.

HttpCookieCollection cookies = Response.Cookies;
for (int i = 0; i < cookies.Count; i++)
{
    HttpCookie cookie = cookies.Get(i);

    if (cookie != null)
    {
        if ((cookie.Name == "ASP.NET_SessionId" || cookie.Name == "ASP.NET_SessionID") && String.IsNullOrEmpty(cookie.Value))
        {
            //Try resetting the expiration date of the session cookie to something in the past and/or deleting it.
            //Reset the expiration time of the cookie to one hour, one minute and one second in the past
            if (Response.Cookies[cookie.Name] != null)
                Response.Cookies[cookie.Name].Expires = DateTime.Today.Subtract(new TimeSpan(1, 1, 1));
        }
    }
}
Cardwell answered 16/3, 2017 at 16:17 Comment(0)
M
1

This was changing for me beginning with .NET 4.7.2 and it was due to the SameSite property on the session cookie. See here for more info: https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/

The default value changed to "Lax" and started breaking things. I changed it to "None" and things worked as expected.

Mortise answered 31/1, 2020 at 23:0 Comment(0)
T
0

Be sure that you do not have a session timeout that is very short, and also make sure that if you are using cookie based sessions that you are accepting the session.

The FireFox webDeveloperToolbar is helpful at times like this as you can see the cookies set for your application.

Tunisia answered 20/5, 2010 at 13:27 Comment(1)
I am guessing my session timeout is not set to below one second. It changes with every rapid F5-press.Overawe
B
0

Session ID resetting may have many causes. However any mentioned above doesn't relate to my problem. So I'll describe it for future reference.

In my case a new session created on each request resulted in infinite redirect loop. The redirect action takes place in OnActionExecuting event.

Also I've been clearing all http headers (also in OnActionExecuting event using Response.ClearHeaders method) in order to prevent caching sites on client side. But that method clears all headers including informations about user's session, and consequently all data in Temp storage (which I was using later in program). So even setting new session in Session_Start event didn't help.

To resolve my problem I ensured not to remove the headers when a redirection occurs.

Hope it helps someone.

Bicycle answered 22/5, 2014 at 10:29 Comment(0)
P
0

I ran into this issue a different way. The controllers that had this attribute [SessionState(SessionStateBehavior.ReadOnly)] were reading from a different session even though I had set a value in the original session upon app startup. I was adding the session value via the _layout.cshtml (maybe not the best idea?)

It was clearly the ReadOnly causing the issue because when I removed the attribute, the original session (and SessionId) would stay in tact. Using Claudio's/Microsoft's solution fixed it.

Piercy answered 1/4, 2016 at 18:14 Comment(0)
F
0

I'm on .NET Core 2.1 and I'm well aware that the question isn't about Core. Yet the internet is lacking and Google brought me here so hoping to save someone a few hours.


Startup.cs

services.AddCors(o => o.AddPolicy("AllowAll", builder =>
            {
                builder
                    .WithOrigins("http://localhost:3000")     // important
                    .AllowCredentials()                       // important
                    .AllowAnyMethod()
                    .AllowAnyHeader();       // obviously just for testing
            }));

client.js

const resp = await fetch("https://localhost:5001/api/user", {
            method: 'POST',
            credentials: 'include',                           // important
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })

Controllers/LoginController.cs

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        [HttpPost]
        public IEnumerable<string> Post([FromBody]LoginForm lf)
        {
            string prevUsername = HttpContext.Session.GetString("username");
            Console.WriteLine("Previous username: " + prevUsername);

            HttpContext.Session.SetString("username", lf.username);

            return new string[] { lf.username, lf.password };
        }
    }
}

Notice that the session writing and reading works, yet no cookies seem to be passed to the browser. At least I couldn't find a "Set-Cookie" header anywhere.

Fecit answered 11/12, 2018 at 11:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.