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.