Принудительное создание HttpContext.Current.Session в .NET - PullRequest
2 голосов
/ 20 сентября 2010

Я работаю над приложением, которое использует StaticFileHandler .NET для обслуживания динамически сгенерированного контента ... Есть также другая часть нашего приложения, которая использует текущий HttpSession для хранения пользовательских данных.

Поскольку StaticFileHandler предназначен для обработки статических файлов, он не реализует IRequiresSessionState, поэтому все, что проходит через эту часть приложения, не имеет доступа к данным сеанса из остальной части приложения.

StaticFileHandler является внутренним для System.Web, поэтому я не могу просто расширить его в свой собственный класс, который также реализует IRequiresSessionState.Есть ли какой-то другой способ, которым я могу форсировать создание сеанса, когда обнаруживаю, что он нулевой?

1 Ответ

1 голос
/ 23 сентября 2010

У нас также был пользовательский поставщик сеансов, который использовал более эффективное кэширование, поэтому я смог воспользоваться этим, чтобы создать сеанс самостоятельно.Вот мой код, если кому-то еще это интересно, но учтите, что вам придется настроить его самостоятельно, если вы хотите заимствовать:

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

Большая часть головоломки - это получение объекта SessionStateStoreData.Если вы используете реализацию по умолчанию, весело проведите время, просматривая рефлектор .NET, чтобы выяснить, как получить к нему доступ!

Кроме того, одним из недостатков этого является то, что SessionStateModule создает cookie только после фактического изменения сеанса.,Однако, просматривая этот код, я вынужден все время создавать cookie, хотя на самом деле я использую сеанс только в очень редком случае.

...