zoukankan      html  css  js  c++  java
  • ASP.NET中Session跨站点共享实现方式

    一、安装session数据库

    使用VS自带的命令工具 到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 目录下面使用命令

    例如:aspnet_regsql.exe -ssadd -sstype c -d [DB]   -S [Server] –E        (使用相应命令可以对远程数据库进行创建)

    具体参数说明参考:http://msdn.microsoft.com/zh-cn/library/ms229862(VS.80).aspx

    其实使用的是文件夹下面的: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.'
                                
    181@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
        }

    以上参考:

    http://www.cnblogs.com/jzywh/archive/2008/11/02/sharesession.html

    五、修改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],而且在我测试的时候两个网站没有使用相同的实体层,实体层的名字不同造成无法转化的问题

    其他参考:

    http://hi.baidu.com/hiqb/blog/item/1b935fee2878b3f7b2fb9542.html

    http://www.cnblogs.com/leonsky/articles/1427014.html

  • 相关阅读:
    使用JavaScriptSerializer进行JSON序列化
    清除浮动
    后台请求url数据
    设置Response中的ContentType
    javascript阻止事件冒泡
    如何启动Nunit的调试功能
    AjaxControlToolKit(整理)二···(全部源代码)
    DataRow对象数据绑定问题
    修改程序之感悟
    关于虚函数一个很好的解释
  • 原文地址:https://www.cnblogs.com/hejunrex/p/2168358.html
Copyright © 2011-2022 走看看