Oturum durumuna bir HTTPModule'dan erişebilir miyim?


85

HTTPModule'ümden bir kullanıcının oturum değişkenlerini güncelleyerek gerçekten yapabilirdim, ancak görebildiğim kadarıyla bu mümkün değil.

GÜNCELLEME: Kodum şu anda OnBeginRequest ()olay işleyicisinin içinde çalışıyor .

GÜNCELLEME: Şimdiye kadar alınan tavsiyeleri takiben, bunu Init ()HTTPModule'ümdeki rutine eklemeyi denedim :

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

Ancak OnPreRequestHandlerExecuterutinimde, oturum durumu hala kullanılamıyor!

Teşekkürler ve bir şeyi kaçırırsam özür dilerim!

Yanıtlar:


83

Bunu ASP.NET forumlarında buldum :

using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Diagnostics;

// This code demonstrates how to make session state available in HttpModule,
// regardless of requested resource.
// author: Tomasz Jastrzebski

public class MyHttpModule : IHttpModule
{
   public void Init(HttpApplication application)
   {
      application.PostAcquireRequestState += new EventHandler(Application_PostAcquireRequestState);
      application.PostMapRequestHandler += new EventHandler(Application_PostMapRequestHandler);
   }

   void Application_PostMapRequestHandler(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState) {
         // no need to replace the current handler
         return;
      }

      // swap the current handler
      app.Context.Handler = new MyHttpHandler(app.Context.Handler);
   }

   void Application_PostAcquireRequestState(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;

      if (resourceHttpHandler != null) {
         // set the original handler back
         HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
      }

      // -> at this point session state should be available

      Debug.Assert(app.Session != null, "it did not work :(");
   }

   public void Dispose()
   {

   }

   // a temp handler used to force the SessionStateModule to load session state
   public class MyHttpHandler : IHttpHandler, IRequiresSessionState
   {
      internal readonly IHttpHandler OriginalHandler;

      public MyHttpHandler(IHttpHandler originalHandler)
      {
         OriginalHandler = originalHandler;
      }

      public void ProcessRequest(HttpContext context)
      {
         // do not worry, ProcessRequest() will not be called, but let's be safe
         throw new InvalidOperationException("MyHttpHandler cannot process requests.");
      }

      public bool IsReusable
      {
         // IsReusable must be set to false since class has a member!
         get { return false; }
      }
   }
}

8
MS bunu düzeltmeli! ... bir Modülü IRequiresSessionState'i uyguluyor olarak işaretlersem, onu elde etmek için bir çemberden atlamak zorunda
kalmam

6
Güzel kod. Buna ihtiyacım olacağını düşündüm, ama olmadı. Bu kod, sunucudan geçen her görüntü ve diğer sayfa dışı kaynak için oturumu yükler. Benim durumumda, PostAcquireRequestState olayında oturumun boş olup olmadığını kontrol ediyorum ve eğer öyleyse geri dönüyorum.
Abtin Forouzandeh

7
Bu kod, istenen kaynak oturum durumunu işlemezse kullanışlıdır. Standart .aspx sayfaları için PostAcquireRequestState olay işleyicisindeki oturuma erişen kodunuzu eklemeniz yeterlidir. Oturum durumu henüz edinilmediği için herhangi bir BeginRequest olay işleyicisinde kullanılamayacaktır.
JCallico

3
Benim durumumda çalışmıyor. "Oturum durumu bu bağlamda kullanılamıyor" mesajını aldım. statik bir dosyaya erişmeye çalışan bir istek olduğunda. Herhangi bir yardım ?
maxisam

3
Bunun statik dosyalar üzerinde çalışması için, ek olarak preCondition = "managedHandler" (<remove name = "Session" /> <add name = ") kaldırarak oturum modülünü (web.config içinde) yeniden kaydettirdim. Oturum "type =" System.Web.SessionState.SessionStateModule "/>)
2014

39

HttpContext.Current.Session , HTTP Modülünüzün oturum durumu başlatılmadan önce meydana gelen herhangi bir ardışık düzen olayını işlemediğini varsayarsak, Çalışmalıdır ...

Açıklamalarda açıklamadan sonra DÜZENLE: BeginRequest olayını işlerken, Session nesnesi henüz ASP.NET çalışma zamanı tarafından başlatılmadığı için gerçekten de boş / Hiçbir şey olacaktır. Bunu aşmak için, işleme kodunuzu PostAcquireRequestState'den sonra oluşan bir olaya taşıyın - bunun için PreRequestHandlerExecute'u seviyorum , çünkü tüm düşük seviyeli işler bu aşamada hemen hemen tamamlanıyor, ancak yine de herhangi bir normal işlemi önceden emiyorsunuz.


Maalesef bu HTTPModule'da mevcut değil - "Nesne başvurusu bir nesnenin bir örneğine ayarlanmadı."
Chris Roberts

'OnBeginRequest' işleniyor mu?
Chris Roberts

Güncelleme için teşekkürler. Bunu Uygulama seviyesinde bir olayda halledersem, neden tüm işlemimi bir HTTPModule kullanmak yerine uygulama seviyesinde yapmıyorum?
Chris Roberts

1
PostAcquireRequeststate 'uygulama düzeyinde bir olay' değildir: örneğin HTTP isteği bir web hizmeti işleyicisi tarafından işleniyorsa, bunu yine de HTTP modülünüzde görürsünüz, ancak Global.asax ...
mdb

Bu benim için güvenilir bir şekilde çalışmıyor gibi görünüyor. Aşağıdaki kod genellikle bir istisnaya neden olur 'Bu bağlamda oturum durumu mevcut değil'. Aslında, VS hata ayıklayıcısını oldukça çarpıcı bir şekilde çökertiyor. context.PreRequestHandlerExecute + = (sender, args) => Console.Write (((HttpApplication) gönderen) .Session ["test"];
cbp

15

İşleyicide HttpContext.Current.Sessionin a erişim IHttpModuleyapılabilir PreRequestHandlerExecute.

PreRequestHandlerExecute : "ASP.NET bir olay işleyicisini (örneğin, bir sayfa veya XML Web hizmeti) yürütmeye başlamadan hemen önce gerçekleşir." Bu, bir 'aspx' sayfası sunulmadan önce bu olayın yürütüldüğü anlamına gelir. 'Oturum durumu' mevcuttur, böylece kendinizi devre dışı bırakabilirsiniz.

Misal:

public class SessionModule : IHttpModule 
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += BeginTransaction;
            context.EndRequest += CommitAndCloseSession;
            context.PreRequestHandlerExecute += PreRequestHandlerExecute;
        }



        public void Dispose() { }

        public void PreRequestHandlerExecute(object sender, EventArgs e)
        {
            var context = ((HttpApplication)sender).Context;
            context.Session["some_sesion"] = new SomeObject();
        }
...
}

Bunu denedim ve gerçekten Seansı aldın. Ama öyle görünüyor ki RequestHeader tam olarak orada değil, özellikle HeaderContentType
Matthias Müller

12

Sayfalar veya işleyiciler aracılığıyla asp.net isteklerine uygulamak istediğiniz yönetilen bir uygulamada normal, temel bir HttpModule yazıyorsanız, oturum oluşturulduktan sonraki yaşam döngüsünde bir olay kullandığınızdan emin olmanız yeterlidir. Begin_Request yerine PreRequestHandlerExecute genellikle gittiğim yerdir. mdb, düzenlemesinde haklıdır.

Başlangıçta soruyu yanıtlamak için listelenen daha uzun kod parçacığı işe yarar, ancak karmaşık ve ilk sorudan daha geniştir. İçeriğin, IRequiresSessionState arabirimini uygulayabileceğiniz bir ASP.net işleyicisine sahip olmayan bir şeyden geldiği durumu ele alır ve böylece oturum mekanizmasını kullanılabilir hale getirmek için tetikler. (Diskteki statik bir gif dosyası gibi). Temel olarak, daha sonra oturumu kullanılabilir hale getirmek için bu arayüzü uygulayan bir kukla işleyici ayarlamaktır.

Yalnızca kodunuz için oturumu istiyorsanız, modülünüzde işlemek için doğru olayı seçin.


0

Deneyin: sınıfta MyHttpModule şunları beyan eder:

private HttpApplication contextapp;

Sonra:

public void Init(HttpApplication application)
{
     //Must be after AcquireRequestState - the session exist after RequestState
     application.PostAcquireRequestState += new EventHandler(MyNewEvent);
     this.contextapp=application;
}  

Ve böylece, aynı sınıftaki başka bir yöntemde (olay):

public void MyNewEvent(object sender, EventArgs e)
{
    //A example...
    if(contextoapp.Context.Session != null)
    {
       this.contextapp.Context.Session.Timeout=30;
       System.Diagnostics.Debug.WriteLine("Timeout changed");
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.