Nhibernate with Asp.net WebForms - Session per Request - asp.net

I am using an HttpModule to open a session that span each request and it works great with lazy loading and everything.
My concern is that since I open a new session per request (and stores it in HttpContext.Current.Items) it opens a session for every request even request including request for .css files and images.
I recall reading that session creation is a pretty lightwheigt operation (dont know about transactions though) but anyway it seems unnecessary to open a session for a requests for a .css file?
Anyone got some ideas about this, is it a problem and/or am I doing something stupid?
Thanks in advance

only create the session object if the file type is .aspx or .ashx:
switch (context.Request.CurrentExecutionFilePathExtension.ToLower())
{
case ".aspx":
case ".ashx":
context.Items[ContextKey] = CreateMySession();
break;
}
or encapsulate session creation inside a property getter, and clean-up checks whether session != null

Related

SpringMVC session managament

I have a simple SpringMVC v3.2.2 controller that does the following:
#RequestMapping(value = { "/login" }, method = RequestMethod.GET)
public String login(WebRequest request) {
request.setAttribute("myattr", "myvalue", SCOPE_SESSION);
}
I'm using the WebRequest object in order to save attributes in the session scope. The SCOPE_SESSION is an integer stating that I want to use it in the session scope. More info on the API is here:
WebRequest API
I assume that it means that I'm adding some attribute that will be saved in the session scope. Session, I assume, will be deleted when the server restarts, during my tests, because I don't want to have any session persisted locally. Unless some default configuration keeps it persisted.
For some reason, the session doesn't get deleted even after tomcat restart(I'm using Tomcat V7, default configuration), meaning that it is persisted for some reason. Tried to find more documentation explaining how to disable it, but could not.
What Am I missing ? if the attribute is saved in the session scope, as the API states, should it get deleted if I restart the Tomcat Server ?
Thanks in advance,
Elad.
I have edited the original question, which was not so clear. Sorry.
Problem solved. I totally missed that the session management is controlled by Tomcat.
The solution was to edit the Tomcat 7 context.xml configuration file and make sure it has the following element :
This disables the session persistence for good. Didn't really think that this is how it works by default. Thank you anyway.

ASP.NET HttpModule : detect first request in a session

I have written a HttpModule for our site which generally accepts requests and checks for specific file extensions as well as the value of a specific session variable. Is it possible to detect the first request in a session?
There's a property on HttpSessionState you can use called IsNewSession, e.g.:
if(Context.Session != null && Context.Session.IsNewSession) {
//do something, session was created this request
}
You can only do this after session state is available of course, but from what you're doing in your module, that doesn't seem to be a problem, please comment if it is.

ASP.NET: Session.SessionID changes between requests

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.
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;
}
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.
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.
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:
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;
}
}
}
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
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
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
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));
}
}
}
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.
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.
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.
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.
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.

Cookies NULL On Some ASP.NET Pages (even though it IS there!)

I'm working on an ASP.NET application and I'm having difficulty in understanding why a cookie appears to be null.
On one page (results.aspx) I create a cookie, adding entries every time the user clicks a checkbox. When the user clicks a button, they're taken to another page (graph.aspx) where the contents of that cookie is read.
The problem is that the cookie doesn't seem to exist on graph.aspx. The following code returns null:
Request.Cookies["MyCookie"];
The weird thing is this is only an issue on our staging server. This app is deployed to a production server and it's fine. It also works perfectly locally.
I've put debug code on both pages:
StringBuilder sb = new StringBuilder();
foreach (string cookie in Request.Cookies.AllKeys)
{
sb.Append(cookie.ToString() + "<br />");
}
this.divDebugOutput.InnerHtml = sb.ToString();
On results.aspx (where there are no problems), I can see the cookies are:
MyCookie
__utma
__utmb
__utmz
_csoot
_csuid ASP.NET_SessionId
__utmc
On graph.aspx, you can see there is no 'MyCookie'
__utma
__utmb
__utmz
_csoot
_csuid ASP.NET_SessionId
__utmc
With that said, if I take a look with my FireCookie, I can see that the same cookie does in fact exist on BOTH pages! WTF?!?!?!?! (ok, rant over :-) )
Has anyone seen something like this before? Why would ASP.NET claim that a cookie is null on one page, and not null on another?
This was happening because I was running the app under a different virtual directory. When I ran it on the original one, it worked.
I would suggest loading the IIS debug diagnostics tools. It is entirely possible that on that particular server there is a resource problem or unhandled exception that is killing that particular cookie AFTER it is added to the response but before it is flushed to the user. This is basically caused by a series of exceptions that occur in rapid succession causing rapid fail protection to shut down the w3wp.exe process that your page is running under. When the process is spooled back up to feed the response, the cookie is gone and all that goes out is the rendered html.
You might also try turning off rapid fail protection or altering memory settings/recycling settings on the application pool.

Asp.net System.Web.HttpContext.Current.Session null in global.asax

I have a custom security principal object which I set in the global.asax for the current thread and all is well, no problems normally.
However, I'm just adding a dynamic image feature by having a page serve up the image and whenever that dynamic image page is loaded the System.Web.HttpContext.Current.Session is null in global.asax which prevents me from setting the security principal as normal and cascading problems from that point onwards.
Normally the Session is null in global.asax only once during a session at the start when the user logs in, afterwards it's always available with this single exception.
The dynamic image page is loaded when the browser comes across an image tage in the original page i.e.
I'm guessing that this is some aspect of the fact that the browser is requesting that page without sending some credentials with it?
Any help would be greatly appreciated.
John,
I'm assuming you're using an ashx handler for the handler. If so, be sure to derive from IRequiresSessionState for example:
public class Images : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{ }
If you're not using an ashx can you describe what you mean by dynamic image page?
Josh
in Global.asax.cs Session_Start() and Session_End() you need to use "this.Session" !!
The reason for this is that HttpContext is only available when there is a request that is being processed. That is why you are getting a NULL on HttpContext.Current.Session!
From Microsoft website:
"HttpContext Class: Encapsulates all HTTP-specific information about an individual HTTP request."
But don't feel bad ... i fell for this one too! :)
Session has nothing to do with being logged in or not.
What event are you overriding when you want access to the session? Session isn't available until AcquireRequestState has been fired.
For more information, see: http://msdn.microsoft.com/en-us/library/9ysfzy8h.aspx
yes you are right This happens because the object dependancy might conficts in case of other page transferance parallel which may break down the firewall between sessions

Resources