Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';我是否与StateServer在两个web应用程序之间共享会话状态?我错过了什么?_C#_Asp.net_Asp.net Mvc_Session_Stateserver - Fatal编程技术网

C# 为什么可以';我是否与StateServer在两个web应用程序之间共享会话状态?我错过了什么?

C# 为什么可以';我是否与StateServer在两个web应用程序之间共享会话状态?我错过了什么?,c#,asp.net,asp.net-mvc,session,stateserver,C#,Asp.net,Asp.net Mvc,Session,Stateserver,我在使用会话状态服务器让两个相同的ASP.NET MVC应用程序共享同一会话时遇到问题。我尝试这样做的原因是,我们最终将在需要共享相同状态的3台web服务器上部署此应用程序。我们需要使用StateServer,因为我们试图将数据库用于非数据相关存储的使用降至最低 设置: 我已将相同的代码库部署到App1和App2 两者都有相同的Web.Config文件,如下所示: <system.web> <sessionState mode="StateServer"

我在使用会话状态服务器让两个相同的ASP.NET MVC应用程序共享同一会话时遇到问题。我尝试这样做的原因是,我们最终将在需要共享相同状态的3台web服务器上部署此应用程序。我们需要使用StateServer,因为我们试图将数据库用于非数据相关存储的使用降至最低

设置:

我已将相同的代码库部署到App1App2

两者都有相同的Web.Config文件,如下所示:

<system.web>
<sessionState mode="StateServer" 
              cookieless="false" 
              timeout="20" 
              stateConnectionString="tcpip=127.0.0.1:42424" />
              //stateConnectionString="tcpip=192.168.1.52:42424" /> // also doesn't work
<machineKey 
  validationKey="8B9F68D0CC730F6F046D0173021C34B1A0D9A01C21D8E4D4A7A1DFF38332DEE8CBBAFEA503C18776614EE9D4F7EEA7E5D2D5571630547D822485A27B1EF53AC1"
  decryptionKey="60009563EFCFC594FD1BC46684943AA398EE70412A624B2EB488BBB071F15ECF"
  validation="SHA1" decryption="AES" />
鉴于此:

<p>
    Mode: <%= ViewData["mode"].ToString() %>
</p>
<p>
    Time: <%= ViewData["timestamp"].ToString() %>
</p>
<p>
    real time: <%= ViewData["realtime"].ToString() %>
</p>

模式:

时间:

实时:

结果:

对于这两种部署,当页面第一次加载时,我可以看到模式是StateServer,时间戳设置为与realtime值相同的时间。。但是,如果这样做有效,则只有第一页的时间应该与realtime值相同。第二个页面加载应该从StateServer读取,因为时间戳值不再为null,并显示该时间值。但是,它会再次显示实时值

刷新页面时,时间戳保持不变,实时值始终在更新。这表示正在将时间戳保存到会话中,但两个部署的时间戳值始终不同(如果时间戳值应该相同),因此这表示未共享会话


有人能指出我是否做错了什么,或者我是否需要做些别的事情来让这一切顺利进行吗?谢谢

默认情况下,会话不能在不同的应用程序之间共享。据我所见,您有两个不同的应用程序
App1
App2
,它们运行在不同的虚拟目录中,甚至可能运行在不同的应用程序池中,因此不要期望在它们之间共享会话


像往常一样,你可能会发现一些有用的东西。正如您所看到的,它使用黑客(反射)来规避ASP.NET team designer不公开某些类和属性的决心,并使我们作为开发人员的生活变得困难。

更新:这是我之前就同一主题回答的帖子

如前所述,会话数据的范围是应用程序。这是您在IIS中创建的应用程序。因此,由于应用程序的作用域,具有相同会话id的两个应用程序将不会共享相同的会话

作为一个可能对你可行也可能不可行的备选方案。 您可以创建一个根应用程序,并将D:\App1和D:\App2的代码放在两个子文件夹中

d:\Root
  web.config
  \App1
     default.aspx
     ...
  \App2
     default.aspx
     ...
然后在IIS中创建一个指向d:\Root的应用程序

您还可以在IIS中创建一个应用程序,然后在该应用程序下创建两个虚拟目录,一个指向D:\App1,另一个指向D:\App2,然后它们还可以在应用程序级别共享一个
web.config
。至关重要的是,这两个虚拟目录只是虚拟的,而不是作为应用程序创建的

所以你的硬盘布局可能是这样的

D:\Root
  web.config

D:\App1
  default.aspx
  ...

D:\App2
  default.aspx
  ...
创建指向D:\root的根应用程序,然后在该应用程序下创建指向D:\App1的两个虚拟目录App1和指向D:\App2的两个虚拟目录App2


这两种情况下的效果是,您实际上将一个应用程序分为两个部分,两个部分都在相同的会话范围内,因此两个部分的代码可以共享相同的会话数据。

您还必须确保应用程序在两个web服务器上的应用程序路径必须相同。这里有一篇老文章可能会有所帮助


我们目前也遇到了类似的问题,只是我们使用的是IIS 7.5,应用程序路径对我们来说是隐藏的(不再使用元数据库)。有人知道IIS 7.5的故障排除方法吗?

实际上,您可以使用Sql server模式共享会话

试试这个:-

我只是改变了程序

USE ASPState
GO

ALTER PROCEDURE dbo.TempGetAppID
    @appName tAppName,
    @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)
SET @appId = NULL

SELECT @appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications
WHERE AppName = @appName

IF @appId IS NULL BEGIN
BEGIN TRAN 

SELECT @appId = AppId
FROM [ASPState].dbo.ASPStateTempApplications WITH (TABLOCKX)
WHERE AppName = @appName

IF @appId IS NULL
BEGIN
EXEC GetHashCode @appName, @appId OUTPUT

INSERT [ASPState].dbo.ASPStateTempApplications
VALUES
(@appId, @appName)

IF @@ERROR = 2627 
BEGIN
DECLARE @dupApp tAppName

SELECT @dupApp = RTRIM(AppName)
FROM [ASPState].dbo.ASPStateTempApplications 
WHERE AppId = @appId

RAISERROR('SQL session state fatal error: hash-code collision between applications ''%s'' and ''%s''. Please rename the 1st application to resolve the problem.', 
18, 1, @appName, @dupApp)
END
END

COMMIT
END

RETURN 0 
GO
使用ASPState
去
ALTER过程dbo.TempGetAppID
@appName tAppName,
@appId int输出
作为
--开始改变
--如果指定了appname,请使用连接中指定的应用程序名称
--这使得我们只需确保站点具有
--连接字符串中的应用程序名称相同。
声明@connStrAppName nvarchar(50)
设置@connstrapName=APP_NAME()
--.NET SQLClient数据提供程序是.NET应用程序的默认应用程序名称
IF(@connstrapName'.NET SQLClient数据提供程序')
设置@appName=@connStrAppName
--换头
设置@appName=LOWER(@appName)
SET@appId=NULL
选择@appId=appId
来自[ASPState].dbo.ASPStateTempApplications
其中AppName=@AppName
如果@appId为空,则开始
开始训练
选择@appId=appId
来自[ASPState].dbo.ASPStateTempApplications和(TABLOCKX)
其中AppName=@AppName
如果@appId为空
开始
EXEC GetHashCode@appName,@appId输出
插入[ASPState].dbo.ASPStateTempApplications
价值观
(@appId,@appName)
如果@@ERROR=2627
开始
声明@dupApp-tAppName
选择@dupApp=RTRIM(AppName)
来自[ASPState].dbo.ASPStateTempApplications
其中AppId=@AppId
RAISERROR('SQL会话状态致命错误:应用程序“%s”和“%s”之间的哈希代码冲突。请重命名第一个应用程序以解决此问题。“”,
18,1,@appName,@dupApp)
结束
结束
犯罪
结束
返回0
去
然后将web.config修改为:-

<sessionState mode="SQLServer" sqlConnectionString="Data Source=.;Integrated Security=True;Application Name=TEST" cookieless="false" timeout="20"></sessionState>
   <httpRuntime targetFramework="4.5"/>

您必须添加应用程序名称,并且对于要共享同一会话的所有应用程序,名称必须相同


谢谢。

没错,它们是不同的应用程序。一个存在于D:\App1中,另一个存在于D:\App2中,并且位于IIS中DefaultWebSite下的不同虚拟目录中。但是,两者都在DefaultAppPool中。原因是我们最终将部署此应用程序
<sessionState mode="SQLServer" sqlConnectionString="Data Source=.;Integrated Security=True;Application Name=TEST" cookieless="false" timeout="20"></sessionState>
   <httpRuntime targetFramework="4.5"/>