Совместное использование сеансов между приложениями с использованием службы состояний сеансов ASP.NET
Я пытаюсь разделить сеансы между двумя веб-приложениями, оба размещены на одном сервере. Одним из них является приложение веб-форм.net 2.0, а другим - приложение.net 3.5 MVC2.
У обоих приложений сессия настроена так:
<sessionState
mode="StateServer"
stateConnectionString="tcpip=127.0.0.1:42424"
/>
В приложении веб-формы я отправляю сеансовый ключ в приложение MVC:
protected void LinkButton1_Click(object sender, EventArgs e)
{
Session["myvariable"] = "dan";
string sessionKey = HttpContext.Current.Session.SessionID;
//Followed by some code that posts sessionKey to the other application
}
Затем я получаю его в приложении MVC и пытаюсь использовать тот же сеанс, как этот:
[HttpPost]
public void Recieve(string sessionKey )
{
var manager = new SessionIDManager();
bool redirected;
bool IsAdded;
manager.SaveSessionID(HttpContext.ApplicationInstance.Context, Id, out redirected, out IsAdded);
var myVar = Session["myvariable"];
}
Ключ публикуется, но, похоже, сессия не загружается в приложение MVC, т.е. sessionKey имеет значение null. Можно ли сделать то, что я пытаюсь сделать?
3 ответа
Я сделал это так:
По сути, идея заключается в том, что оба приложения используют собственный.net sessionState, хранящийся в sqlserver. Используя один и тот же ключ компьютера и внося небольшие изменения в хранимую процедуру, оба приложения могут совместно использовать любые ключи сеанса и / или формы аутентификации.
Оба приложения будут делать что-то подобное в своем файле web.config:
<sessionState mode="SQLServer" sqlConnectionString="Data Source=.\SQLEXPRESS;User Id=test;Password=test;Application Name=AppName" />
<machineKey
validationKey="SOMEKEY"
validation="SHA1" decryption="AES"
/>
Состояние сеанса db должно быть настроено на сервере базы данных, который могут видеть оба приложения.
Документы для этого: http://msdn.microsoft.com/en-us/library/ms229862(VS.80).aspx
Команда, которую нужно выполнить: C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>aspnet_regsql.exe -E -ssadd --sstype p -S .\SQLEXPRESS
Хранимая процедура (TempGetAppID) позволяет:
@appId int OUTPUT
AS
-- start change
-- Use the application name specified in the connection for the appname if specified
-- This allows us to share session between sites just by making sure they have the
-- the same application name in the connection string.
DECLARE @connStrAppName nvarchar(50)
SET @connStrAppName = APP_NAME()
-- .NET SQLClient Data Provider is the default application name for .NET apps
IF (@connStrAppName <> '.NET SQLClient Data Provider')
SET @appName = @connStrAppName
-- end change
SET @appName = LOWER(@appName)
Проблема заключается в том, что сеансовые ключи ограничены приложениями, поэтому два приложения, имеющие один и тот же сеансовый ключ, фактически имеют отдельные сеансы.
Вы можете сделать одну из двух вещей:
Поместите оба приложения как виртуальный каталог в общее приложение IIS. Я не думаю, что это хорошая идея, но она будет работать.
Сверните свое собственное решение для сеансовых данных, которыми вы хотите поделиться. Возможно использование базы данных в качестве общего хранилища, если оно у вас есть.
Исходя из комментария Джастина, просто чтобы уточнить вариант 2 не относится к управлению состоянием SQL для сеансов вне процесса. Я имею в виду, что вы на самом деле вручную управляете общими данными для двух сессий, возможно, используя базу данных.
Вы можете использовать общий ключ компьютера для генерации идентификатора сеанса в обоих приложениях для данного пользователя. Кроме того, вы должны также планировать хранение сеансов обоих приложений в общем хранилище, таком как ASP.NET State Service или распределенный кеш.
Вы можете использовать распределенный кеш NCache, который обеспечивает возможность совместного использования сеанса между различными приложениями. Вы задаете один и тот же тег идентификатора приложения для обоих приложений в настройках состояния сеанса, что позволяет вам совместно использовать объект сеанса, если у вас есть один и тот же идентификатор сеанса, созданный для обоих приложений.