使用ASP.NET会话状态服务跨应用程序共享会话

Dan*_*Dan 48 c# asp.net asp.net-mvc session-state

我正在尝试在两个Web应用程序之间共享会话,这两个Web应用程序都托管在同一台服 一个是.net 2.0 Web表单应用程序,另一个是.net 3.5 MVC2应用程序.

两个应用程序的会话都设置如下:

<sessionState
      mode="StateServer"
      stateConnectionString="tcpip=127.0.0.1:42424"
      />
Run Code Online (Sandbox Code Playgroud)

在webform应用程序中,我将会话密钥发布到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    
}
Run Code Online (Sandbox Code Playgroud)

然后我在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"];

}
Run Code Online (Sandbox Code Playgroud)

密钥正在发布但会话似乎没有加载到MVC应用程序中,即sessionKey为null.可以做我想做的事吗?

Dan*_*Dan 73

我是这样做的:

基本上这个想法是两个应用程序都使用存储在sqlserver中的本机.net sessionState.通过使用相同的机器密钥并对存储过程进行小调整 - 两个应用程序都可以共享任何会话密钥和/或表单验证.

两个应用程序都会在web.config中执行类似的操作:

<sessionState mode="SQLServer" sqlConnectionString="Data Source=.\SQLEXPRESS;User Id=test;Password=test;Application Name=AppName"  />
    <machineKey
validationKey="SOMEKEY"
validation="SHA1" decryption="AES"
/>
Run Code Online (Sandbox Code Playgroud)

需要在数据库服务器上设置会话状态数据库,这两个应用程序都可以看到.

这样做的文档: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)
Run Code Online (Sandbox Code Playgroud)

  • 生活并不是那么完美.这个解决方案有一些错误.我一直在开始使用它,并注意到过时的会话行没有从db中删除.所以它非常增长,我得到了异常"数据库'ASPState'的事务日志已满." 一段时间后.我该如何解决? (2认同)
  • @RredCat:在设置数据库时使用带有-sstype p参数的aspnet_regsql.exe,他正在选择一个持久化数据存储区.保持此参数关闭,默认使用"tempdb"数据库. (2认同)

Chr*_*lor 9

问题是会话密钥的范围限定为应用程序,因此具有相同会话密钥的两个应用程序实际上具有单独的会话.

你可以做以下两件事之一:

  1. 将两个应用程序作为虚拟目录放在公共IIS应用程序下.我认为这不是一个好主意,但它会起作用.

  2. 为您要共享的数据滚动自己的会话数据解决方案.可能使用后端数据库作为公共存储,如果你有一个.

根据Justin的评论,只是为了澄清选项2并未引用进程外会话的SQL状态管理.我的意思是你实际上可以使用数据库手动管理两个会话的共享数据.