Подтвердить что ты не робот

Доступ к сеансу в трубопроводах HttpRequest

Я пытаюсь получить доступ к параметру строки запроса и сохранить его в переменной Session. Поскольку решение, над которым я работаю, имеет несколько базовых макетов, самым простым подходом было бы добавить это в обработчик конвейера. Однако мой код не работает, потому что args.Context.Session имеет значение null:

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. Любопытно узнать, почему, и если есть стандартный обходной путь или шаблон для использования здесь. (Да, я добавлю нулевую проверку. Не нужно указывать это.)

Я запускаю Sitecore Sitecore.NET 6.4.1 (rev. 110720) на IIS 7.5 (Integrated.Net 2.0)

Возможно релевантные ссылки:

4b9b3361

Ответ 1

Конвейер HttpRequestBegin подключен к событию HttpApplication.BeginRequest, и это событие запускается до того, как объект HttpSession был создан. Использование конвейера HttpRequestEnd не работает, потому что объект HttpSession уже был удален к моменту запуска события HttpApplication.EndRequest.

Сессия становится доступной после запуска события PostAcquireRequestState. Чтобы перехватить это, создайте класс, реализующий IHttpModule, и добавьте его в <httpModules> элемент в Web.config. Код HttpModule должен будет проверить, требует ли запрос состояние сеанса, поскольку попытка прочитать сеанс для запроса статического ресурса вызовет исключение.

Вот код HttpModule, который обращается к Session и QueryString:

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 подключены к ASP.NET через HttpModule:

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

Спасибо @ddysart за то, что указали мне в правильном направлении, и этот ответ за правильное событие для прослушивания.

Ответ 2

Фактически вместо httpRequestBegin или HttpRequestEnd вы можете использовать httpRequestProcessed, в течение которого 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;
    }
}