18

我正在尝试访问查询字符串参数并将其保存到 Session 变量中。由于我正在研究的解决方案有几个基本布局,最简单的方法是将其添加到管道处理程序中。但是,我的代码失败了,因为 args.Context.Session 为空:

public class SaveQueryStringToSession : HttpRequestProcessor
{
    public override void Process(HttpRequestArgs args)
    {
        Assert.ArgumentNotNull((object)args, "args");
        string queryString = WebUtil.GetQueryString("parm1");
        if (queryString.Length <= 0)
            return;
        args.Context.Session["parm1"] = queryString;
    }
}

当此方法插入 HttpRequestBegin 或 HttpRequestEnd 管道时,会发生这种情况。很想知道为什么,以及是否有标准的解决方法或模式可以在这里使用。(是的,我将添加一个空检查。无需指出。)

我在 IIS 7.5(集成的 .Net 2.0)上运行 Sitecore Sitecore.NET 6.4.1(修订版 110720)

可能相关链接:

4

2 回答 2

22

HttpRequestBegin 管道连接到 HttpApplication.BeginRequest 事件,并且在实例化 HttpSession 对象之前触发此事件。使用 HttpRequestEnd 管道不起作用,因为在触发 HttpApplication.EndRequest 事件时 HttpSession 对象已被释放。

触发 PostAcquireRequestState 事件后,会话变为可用。要截获此问题,请创建一个实现 IHttpModule 的类,并将其添加到 Web.config 中的 <httpModules> 元素中。HttpModule 代码需要检查请求是否需要会话状态,因为尝试读取静态资源请求的会话将引发异常。

这是访问 Session 和 QueryString 的 HttpModule 代码:

public class MyHttpModule :IHttpModule
{
   public void Init(HttpApplication context)
   {
       context.PostAcquireRequestState += RequestHandler;
   }

   public void Dispose()
   {
        //
   }

   public void RequestHandler(object sender, EventArgs e)
   {
       var app = (HttpApplication) sender;

       if (app.Context.Handler is IRequiresSessionState)
       {
           var session = app.Session;
           var queryString = app.Request.QueryString["test"];
           session["test"] = queryString;
       }
   }
}

值得注意的是,Sitecore 的 HttpRequestBegin 和 HttpRequestEnd 管道通过 HttpModule 连接到 ASP.NET:

<add type="Sitecore.Nexus.Web.HttpModule,Sitecore.Nexus" 
name="SitecoreHttpModule" />

感谢@ddysart 为我指明了正确的方向,并感谢答案以获取正确的事件。

于 2012-11-13T06:13:59.263 回答
5

实际上,您可以使用 httpRequestProcessed 而不是 httpRequestBegin 或 HttpRequestEnd,在此期间,sitecore 处理 HttpRequest 以便您可以访问会话。

您将能够使用之前提供的相同代码。

public class SaveQueryStringToSession : HttpRequestProcessor
{
   public override void Process(HttpRequestArgs args)
   {
        Assert.ArgumentNotNull((object)args, "args");
        string queryString = WebUtil.GetQueryString("parm1");
        if (queryString.Length <= 0)
            return;
        args.Context.Session["parm1"] = queryString;
    }
}
于 2015-10-30T15:07:02.493 回答