Forcing creation of HttpContext.Current.Session in .NET
I'm working on an application that uses .NET's StaticFileHandler to serve up dynamically generated content... There is also another part of our application开发者_JAVA技巧 that uses the current HttpSession to store user-specific data.
Since the StaticFileHandler is designed to handle static files, it doesn't implement IRequiresSessionState, thus anything going through that part of the app doesn't have access to the session-specific data from the rest of the app.
StaticFileHandler is internal to System.Web so I can't just extend it into my own class that also implements IRequiresSessionState. Is there some other way I can force creation of the session when I detect that it's null?
We also had a custom session provider that was using some more efficient caching, so I was able to piggyback off of that to create the session myself. Here's my code if anybody else is interested, but note that you'll have to tweak it yourself if you want to borrow:
public void EnsureSessionExists(HttpContext context) {
if (context.Session != null) {
// Hey, we've already got a session. That was easy...
return;
}
bool isNew = false;
string sesId = _sessionIdManager.GetSessionID(context);
if (String.IsNullOrEmpty(sesId)) {
// if ID is null or empty, it means we're creating a new session?
sesId = _sessionIdManager.CreateSessionID(context);
}
SessionStateStoreData data = GetSessionDataStore(context, sesId);
if (data == null) {
isNew = true;
data = CreateNewStoreData(context, _sessionTimeout);
// Create doesn't put it in the cache. This does.
SetSessionDataStore(context, sesId, data);
}
HttpSessionStateContainer container = new HttpSessionStateContainer(sesId, data.Items, data.StaticObjects, data.Timeout, isNew, HttpCookieMode.UseCookies, SessionStateMode.Custom, false);
SessionStateUtility.AddHttpSessionStateToContext(context, container);
// Force the cookie to get set here. SessionStateModule only sets it if the Handler has IRequiresSessionState
HttpCookie cookie = new HttpCookie("ASP.NET_SessionId", _sessionIdManager.Encode(sesId));
cookie.Expires = DateTime.MinValue; // DateTime.MinValue makes it a session cookie.
context.Response.Cookies.Add(cookie);
}
The big piece of the puzzle is the part about getting the SessionStateStoreData object. If you're using the default implementation, have fun looking through .NET reflector to figure out how to access it!
Also, one downside to this is that the SessionStateModule only creates a cookie once the session is actually changed. Going through this code, however, I'm forced to create the cookie all the time, even though I'm actually only using the session in a very rare case.
精彩评论