一、安装session数据库
使用VS自带的命令工具 到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 目录下面使用命令
例如:aspnet_regsql.exe -ssadd -sstype c -d [DB] -S [Server] –E (使用相应命令可以对远程数据库进行创建)
具体参数说明参考:
其实使用的是文件夹下面的:InstallSqlState.sql 与InstallPersistSqlState.sql 前一个是在temp数据库中,重启数据库将会session丢失,后一个在独立数据库中,重启数据库session不会丢失
但是在数据库中直接使用这两个文件进行创建将会出现错误,不知道代理服务开始时候还会出现,但是使用命令就算代理服务没有开启也是可以创建的
二、配置web.config
<sessionState mode="SQLServer" sqlConnectionString="data source=[Server];initial catalog=[DB];user id=[User Name];password=[Password]" cookieless="false" timeout="60"></sessionState>
三、修改数据库存储过程
通过以上配置session已经保存在数据库中,但是不同的站点其SessionID是不同的,就算SessionID相同了,保存在会话数据库中的实际SessionID的值也不只是网站生成的SessionID,而是在SessionID后加上了站点的AppName,因此即使各个站点共享了会话数据库也不能共享会话数据。
CREATE PROCEDURE dbo.TempGetAppID @appName tAppName, @appId int OUTPUT AS SET @appName = LOWER ( @appName ) SET @appId = NULL SELECT @appId = AppId FROM [ JSEC_SessionDB ] .dbo.ASPStateTempApplications WHERE AppName = @appName IF @appId IS NULL BEGIN BEGIN TRAN SELECT @appId = AppId FROM [ JSEC_SessionDB ] .dbo.ASPStateTempApplications WITH (TABLOCKX) WHERE AppName = @appName IF @appId IS NULL BEGIN EXEC GetHashCode @appName , @appId OUTPUT INSERT [ JSEC_SessionDB ] .dbo.ASPStateTempApplications VALUES ( @appId , @appName ) IF @@ERROR = 2627 BEGIN DECLARE @dupApp tAppName SELECT @dupApp = RTRIM (AppName) FROM [ JSEC_SessionDB ] .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 修改以上第五行 set @appName='XXX' 任意值使每个站点使用相同的appName
四、修改Cookie保存方式确保cookie使用相同主域
public class CrossDomainCookie : IHttpModule { private string m_RootDomain = string .Empty; #region IHttpModule Members public void Dispose() { } public void Init(HttpApplication context) { m_RootDomain = ConfigurationManager.AppSettings[ " RootDomain " ]; Type stateServerSessionProvider = typeof (HttpSessionState).Assembly.GetType( " System.Web.SessionState.OutOfProcSessionStateStore " ); FieldInfo uriField = stateServerSessionProvider.GetField( " s_uribase " , BindingFlags.Static | BindingFlags.NonPublic); if (uriField == null ) throw new ArgumentException( " UriField was not found " ); uriField.SetValue( null , m_RootDomain); context.EndRequest += new System.EventHandler(context_EndRequest); } void context_EndRequest( object sender, System.EventArgs e) { HttpApplication app = sender as HttpApplication; for ( int i = 0 ; i < app.Context.Response.Cookies.Count; i ++ ) { app.Context.Response.Cookies[i].Domain = m_RootDomain; } } #endregion } 以上参考:
五、修改web.config
< appSettings > < add key ="RootDomain" value =".test.com" /> </ appSettings > < system.web > < machineKey decryptionKey ="FD69B2EB9A11E3063518F1932E314E4AA1577BF0B824F369" validationKey ="5F32295C31223A362286DD5777916FCD0FD2A8EF882783FD3E29AB1FCDFE931F8FA45A8E468B7A40269E50A748778CBB8DB2262D44A86BBCEA96DCA46CBC05C3" validation ="SHA1" decryption ="Auto" /> < sessionState mode ="SQLServer" sqlConnectionString ="data source=[Server];initial catalog=[DB];user id=[User Name];password=[Password]" cookieless ="false" timeout ="60" ></ sessionState > < httpModules > < add name ="CrossDomainCookieModule" type ="Test.HttpModule.CrossDomainCookie, GB87.HttpModule" /> </ httpModules > </ system.web > < system.webServer > < modules > < add name ="CrossDomainCookieModule" preCondition ="managedHandler" type ="Test.HttpModule.CrossDomainCookie, GB87.HttpModule" /> </ modules > </ system.webServer > 以上完成了 所有的配置
接下来就是配置在IIS上面 创建两个网站 http://www.test.com/ http://a.test.com/
并修改host文件 指向127.0.0.1 进行测试 通过测试
配置使用过程中发现的问题:
在使用session保存对象的时候一定要能够序列化,类名前面加[Serializable],而且在我测试的时候两个网站没有使用相同的实体层,实体层的名字不同造成无法转化的问题
其他参考: