2012-08-29 110 views
3

我們的ASP.NET應用程序在同一會話上並行發送多個Ajax請求。在其中一些請求中,我們還讀取/寫入HttpSessionState。我想要的是所有併發請求都是由於性能原因而並行執行的。我得到的是他們被ASP.NET序列化。我嘗試過配置enableSessionState="ReadOnly",但這打破了我們的表單身份驗證。ASP.NET會話狀態提供程序

有沒有辦法在一個會話中同時獲得會話狀態和併發?我需要使用自定義的SessionState還是Provider?這裏的任何樣品?

PS我不擔心訪問SessionState時的線程安全性 - 我可以通過編程來實現。

回答

2

從MSDN(link):

但是,如果兩個併發請求爲同一會議上提出的(通過使用相同的SessionID值),第一個請求獲取會話信息的獨佔訪問。第二個請求僅在第一個請求完成後執行。

因此,至少對於那些需要對會話進行寫訪問的AJAX調用,您對運行默認提供程序是不好的。

不確定您是否可以使用自定義提供程序解決此問題。

可以實現不通過在HttpModule阻斷ASP.NET_SessionId餅乾需要訪問會話的AJAX調用parallell執行。看到我的answer到這個question

編輯:爲了使這個答案更加自力更生,我添加了HttpModule,並略加修改了一下討論(進一步下跌)。下面是您可以使用,以防止序列化的Ajax的會話狀態的模塊代碼調用:

using System; 
using System.Web; 

namespace TestModule 
{ 
    public class TestPreventCookie : IHttpModule 
    { 
     public void Dispose() 
     { 
     } 
     public void Init(HttpApplication application) 
     { 
      application.BeginRequest += 
       (new EventHandler(this.Application_BeginRequest)); 
      application.PostAcquireRequestState += 
       (new EventHandler(this.Application_PostAcquireRequestState)); 

     } 
     private void Application_BeginRequest(Object source, EventArgs e) 
     { 
      //prevent session cookie from reaching the service 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 
      if (BlockCookie(context)) 
      { 
       context.Request.Cookies.Remove("ASP.NET_SessionId"); 
      } 
     } 
     private void Application_PostAcquireRequestState(Object source, EventArgs e) 
     { 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 
      if (BlockCookie(context)) 
      { 
       var s = context.Session; 
       if (s != null) 
        s.Abandon(); 
      } 
     } 
     private bool BlockCookie(HttpContext context) 
     { 
      // put code here that determines if the session cookie should be blocked 
      // this could be based on the path of the current request for instance 
      // only block the cookie when you *know* that access to the Session is not needed 
     } 
    } 
} 

此模塊背後的想法是,使用基於項目需求的一些標準,我們從當前的情況下刪除ASP.NET_SessionId餅乾(請注意,我們不會在客戶端上過期)。

這意味着進一步在請求管道中,服務器將創建一個新的會話。爲了防止這個新創建的會話破壞客戶端上現有的ASP.NET_SessionId cookie,我們在創建後立即放棄它。

最終的結果是,模塊「攔截」的每個請求都會執行,就好像它沒有會話一樣。