Совместное использование состояния сеанса между различными версиями .NET с использованием State Server

Фон

  • У нас есть один веб-сайт, работающий на IIS 6 (сервер Win2003) с использованием .NET 3.5: site1.mysite.local
  • У нас есть второй веб-сайт, работающий на IIS 7 (сервер Win2008) с использованием .NET 4.0: site2.mysite.local

На каждом сайте web.config содержит StateServer и тот же файл machineKey:

<sessionState mode="StateServer" stateConnectionString="tcpip=STATESRV01:42424" />

<machineKey decryptionKey="EDCDA6DF458176504BBCC720B4E29348E252E652591179E2" validationKey="CC482ED6B5D3569819B3C8F07AC3FA855B2FED7F0130F55D8405597C796457A2F5162D35C69B61F257DB5EFE6BC4F6CEBDD23A4112C4519F55185CB5EB3DFE61"/>

У нас также есть обработчик событий PostRequestHandlerExecute, чтобы изменить файл cookie "NET_SessionId", чтобы иметь тот же корневой домен и путь.

cookie.Domain = ".mysite.local";
cookie.Path = "/";

В файле global.asax у нас есть следующий код для изменения имени приложения в событии Application_Start:

    protected void Application_Start(object sender, EventArgs e)
    {
        string applicationName = "mysiteapp";

        // Change the Application Name in runtime.
        FieldInfo runtimeInfo = typeof(HttpRuntime).GetField("_theRuntime",
            BindingFlags.Static | BindingFlags.NonPublic);
        HttpRuntime theRuntime = (HttpRuntime)runtimeInfo.GetValue(null);
        FieldInfo appNameInfo = typeof(HttpRuntime).GetField("_appDomainAppId",
            BindingFlags.Instance | BindingFlags.NonPublic);

        appNameInfo.SetValue(theRuntime, applicationName);
    }

Результат

Оба сайта возвращают один и тот же идентификатор сеанса, но когда мы пытаемся установить значение сеанса на сайте1, site2 не возвращает значение.

Сайт 1 (site1.mysite.local) Результат

Session ID (Session.SessionID): a55jnfcscxd3f0hnwoik02pp
Session Value: True

Сайт 2 (site2.mysite.local) Результат

Session ID (Session.SessionID): a55jnfcscxd3f0hnwoik02pp
Session Value: 

Вопрос

С моей точки зрения, государственный сервер закрывает сеанс комбинации cookie SessionID, машинного ключа и имени приложения, которое мы пытались обновить, поэтому на обоих сайтах оно одинаково. Проблема заключается в том, что значение сеанса не распространяется на веб-сайты.

Почему вы не используете режим SQL Server для состояния сеанса?

Возможно, нам придется, но мы надеялись использовать наш сервер состояний.

Кто-нибудь имел успех с State Server с несколькими веб-приложениями на нескольких серверах?

Ответы

Ответ 1

.NET 3.5 и .NET 4 запускают разные версии CLR. Сериализация объектов (которая используется для хранения состояния сеанса при использовании InProc) отличается от версий .NET. Скорее всего, объект не будет десериализован на другой платформе, чтобы он молча удалял его. У вас будет такая же проблема, если вы также используете SQL Server в качестве сервера состояния сеанса.

Предполагая, что это проблема, вам нужно будет обеспечить, чтобы оба сайта находились на одной и той же версии .NET или выполняли собственную сериализацию на диск или SQL Server.

Ответ 2

Управление состояниями StateServer и SQLServer также использует путь приложения (в дополнение к имени приложения) при создании ключа для данных сеанса.

Ваше приложение показывает тот же SessionID из-за того, что cookie читается обоими приложениями, однако путь приложения должен быть таким же, чтобы фактически прочитать одни и те же данные сеанса на государственном сервере.

Вы можете изменить это на одно значение с дополнительной перезаписью в Application_Start для этой переменной:

FieldInfo appPathInfo = typeof(HttpRuntime).GetField("_appDomainAppPath",
     BindingFlags.Instance | BindingFlags.NonPublic);

appPathInfo .SetValue(theRuntime, applicationName);