【问题标题】:ASP.NET Session State ProvidersASP.NET 会话状态提供程序
【发布时间】:2012-08-23 23:07:22
【问题描述】:

我们的 ASP.NET 应用在同一个会话中并行发送多个 Ajax 请求。在其中一些请求期间,我们还会读/写HttpSessionState。我想要的是所有并发请求出于性能原因并行执行。我得到的是它们由 ASP.NET 序列化。我尝试配置enableSessionState="ReadOnly",但这会破坏我们的表单身份验证。

有没有办法在一个会话中同时获得会话状态和并发?我需要使用自定义SessionStateProvider 吗?有这样的样本吗?

PS 在访问 SessionState 时,我并不担心线程安全 - 我可以通过编程方式做到这一点。

【问题讨论】:

    标签: asp.net ajax session session-state


    【解决方案1】:

    来自 MSDN (link):

    但是,如果对同一个会话发出两个并发请求(通过使用相同的 SessionID 值),则第一个请求将获得对会话信息的独占访问权。第二个请求只有在第一个请求完成后才会执行。

    因此,至少对于那些需要对 Session 进行写访问的 AJAX 调用,您对默认提供程序不走运。

    不确定您是否可以使用自定义提供程序解决此问题。

    可以通过阻止HttpModule 中的ASP.NET_SessionId cookie 来实现那些不需要访问会话的AJAX 调用的并行执行。看到我的answer 到这个question

    编辑:为了使这个答案更加独立,我添加了HttpModule 的略微修改版本和一些讨论(进一步向下)。下面是可用于防止 Session 状态序列化 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 cookie(注意,我们不会在客户端上使其过期)。

    这意味着在请求管道中,服务器将创建一个新会话。为了防止这个新创建的会话破坏客户端现有的ASP.NET_SessionId cookie,我们在它创建后立即放弃它。

    最终结果是每个被模块“拦截”的请求都会像没有会话一样执行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-21
      • 2011-06-23
      • 1970-01-01
      • 2015-06-18
      • 2013-03-12
      • 2015-03-10
      • 2015-11-28
      • 2011-06-09
      相关资源
      最近更新 更多