क्या मैं एक HTTPModule से सत्र स्थिति तक पहुँच सकता हूँ?


85

मैं वास्तव में अपने HTTPModule के भीतर से उपयोगकर्ता के सत्र चर को अपडेट करने के साथ कर सकता था, लेकिन मैं जो देख सकता हूं, वह संभव नहीं है।

अद्यतन: मेरा कोड वर्तमान में OnBeginRequest ()ईवेंट हैंडलर के अंदर चल रहा है ।

अद्यतन: अब तक मिली सलाह के बाद, मैंने Init ()अपने HTTPModule में इसे दिनचर्या में जोड़ने की कोशिश की :

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

लेकिन मेरी OnPreRequestHandlerExecuteदिनचर्या में, सत्र राज्य अभी भी अनुपलब्ध है!

धन्यवाद, और माफी माँगता हूँ अगर मैं कुछ याद कर रहा हूँ!

जवाबों:


83

ASP.NET मंचों पर यह मिला :

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 को इसे ठीक करना चाहिए! ... यदि मैं IRequiresSessionState को लागू करने के रूप में एक मॉड्यूल को चिह्नित करता हूं, तो मुझे इसे प्राप्त करने के लिए एक घेरा कूदना नहीं चाहिए ... (सेक्सी कोड वास्तव में)
BigBlondeViking

6
अच्छा कोड है। मैंने सोचा कि मुझे इसकी आवश्यकता होगी, लेकिन यह पता नहीं चला। यह कोड सर्वर के माध्यम से जाने वाली प्रत्येक छवि और अन्य गैर-पृष्ठ संसाधन के लिए सत्र लोड करना समाप्त करता है। मेरे मामले में, मैं बस जाँच करता हूं कि क्या सत्र PostAcquireRequestState इवेंट में शून्य है और यदि यह है तो वापस लौटें।
अबतिन फोउन्जंडेह

7
यदि संसाधन अनुरोध सत्र स्थिति को हैंडल नहीं करता है तो यह कोड उपयोगी है। मानक .aspx पृष्ठों के लिए केवल PostAcquireRequestState ईवेंट हैंडलर पर सत्र को एक्सेस करने वाला अपना कोड जोड़ें। सत्र राज्य किसी भी प्रारंभिक इवेंट हैंडलर पर उपलब्ध नहीं होगा क्योंकि सत्र राज्य अभी तक अधिग्रहित नहीं किया गया है।
जेलिको

3
यह मेरे मामले में काम नहीं करता है। मैंने कहा "इस संदर्भ में सत्र राज्य उपलब्ध नहीं है।" जब एक स्थिर फ़ाइल तक पहुँचने के लिए एक अनुरोध है। कोई मदद ?
मैक्सिमम

3
इसके लिए स्थैतिक फ़ाइलों पर काम करने के लिए, मेरे पास, इसके अलावा, सत्र मॉड्यूल (web.config में) प्री-कंडिशन = "प्रबंधितहैंडलर" (<निकालें नाम = "सत्र" /> <<add = "को हटाकर पुनः पंजीकृत करें) सत्र "प्रकार ="
सिस्टम ।eb.SessionState.SessionStateModule

39

HttpContext.Current.Session को बस काम करना चाहिए, यह मानते हुए कि आपका HTTP मॉड्यूल किसी भी पाइपलाइन की घटनाओं को नहीं संभाल रहा है, जो सत्र राज्य से पहले होने वाली घटनाओं को इनिशियलाइज़ किया जा रहा है ...

EDIT, टिप्पणियों में स्पष्टीकरण के बाद: BeginRequest घटना को संभालने के दौरान , सत्र ऑब्जेक्ट वास्तव में अभी भी अशक्त / कुछ भी नहीं होगा, क्योंकि इसे ASP.NET रनटाइम द्वारा अभी तक आरंभ नहीं किया गया है। इसके आस-पास काम करने के लिए, अपने हैंडलिंग कोड को एक इवेंट में ले जाएं जो PostAcquireRequestState के बाद होता है - मुझे उसके लिए PreRequestHandlerExecute पसंद है , क्योंकि इस स्तर पर सभी निम्न-स्तरीय कार्य बहुत अधिक किए जाते हैं, लेकिन आप अभी भी किसी भी सामान्य प्रसंस्करण को पूर्व-खाली करते हैं।


दुर्भाग्य से यह HTTPModule में उपलब्ध नहीं है - "ऑब्जेक्ट संदर्भ किसी ऑब्जेक्ट की आवृत्ति पर सेट नहीं है।"
क्रिस रॉबर्ट्स

मैं 'OnBeginRequest' संसाधित कर रहा हूं?
क्रिस रॉबर्ट्स

अद्यतन के लिए धन्यवाद। अगर मैं इसे एक एप्लिकेशन स्तर की घटना में संभालता हूं, तो मैं HTTPModule का उपयोग करने के बजाय सिर्फ अपने सभी प्रसंस्करण स्तर पर ही क्यों नहीं करूं?
क्रिस रॉबर्ट्स

1
PostAcquireRequeststate एक 'एप्लिकेशन स्तर घटना' नहीं है: यदि HTTP अनुरोध को वेब सेवा हैंडलर द्वारा नियंत्रित किया जाता है, उदाहरण के लिए, आप अभी भी इसे अपने HTTP मॉड्यूल में देखेंगे, लेकिन Global.asax में नहीं ...
mdv

यह मेरे लिए मज़बूती से काम नहीं करता है। निम्नलिखित कोड अक्सर एक अपवाद का कारण होगा 'सत्र राज्य इस संदर्भ में उपलब्ध नहीं है'। वास्तव में, यह वीएस डीबगर को बहुत शानदार ढंग से क्रैश करता है। सन्दर्भ।प्रेरणाधिकारीहांडलर एक्स्यूट्यूट + = (प्रेषक, आर्ग्स) => कंसोल.व्रीत (((HttpApplication)) प्रेषक)। सत्र ["परीक्षण"];
cbp

15

कर सकते हैं HttpContext.Current.Sessionमें प्रवेश हैंडलर IHttpModuleमें किया जा सकता है PreRequestHandlerExecute

PreRequestHandlerExecute : "ASP.NET के ठीक पहले एक घटना हैंडलर (उदाहरण के लिए, एक पेज या एक XML वेब सेवा) निष्पादित करना शुरू होता है।" इसका मतलब है कि 'एस्पेक्स' पेज परोसने से पहले इस घटना को अंजाम दिया जाता है। 'सत्र स्थिति' उपलब्ध है, ताकि आप स्वयं को बाहर निकाल सकें।

उदाहरण:

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();
        }
...
}

मैंने यह कोशिश की, और आपको सत्र वास्तव में मिलता है। लेकिन ऐसा लगता है कि RequestHeader पूरी तरह से नहीं है, स्पष्ट रूप से हैडरकंटेंट टाइप
Matthias Müller

12

यदि आप एक सामान्य अनुप्रयोग में एक सामान्य, बेसिक HttpModule लिख रहे हैं, जिसे आप पृष्ठों या हैंडलर के माध्यम से asp.net अनुरोधों पर लागू करना चाहते हैं, तो आपको बस यह सुनिश्चित करना होगा कि आप सत्र निर्माण के बाद जीवनचक्र में किसी घटना का उपयोग कर रहे हैं। Pre_equestHandlerExecute के बजाय Begin_Request आमतौर पर जहाँ मैं जाता हूँ। mdb ने इसे अपने संपादन में सही किया है।

मूल कोड स्निपेट मूल रूप से प्रश्न कार्यों के उत्तर के रूप में सूचीबद्ध है, लेकिन प्रारंभिक प्रश्न की तुलना में जटिल और व्यापक है। यह उस मामले को संभालेगा जब सामग्री ऐसी चीज़ से आ रही है जिसमें ASP.net हैंडलर उपलब्ध नहीं है जहाँ आप IRequiresSessionState इंटरफ़ेस को लागू कर सकते हैं, इस प्रकार सत्र तंत्र को ट्रिगर करके इसे उपलब्ध कर सकते हैं। (डिस्क पर एक स्थिर GIF फ़ाइल की तरह)। यह मूल रूप से एक डमी हैंडलर सेट कर रहा है जो सत्र को उपलब्ध कराने के लिए उस इंटरफ़ेस को लागू करता है।

यदि आप अपने कोड के लिए सत्र चाहते हैं, तो बस अपने मॉड्यूल में हैंडल करने के लिए सही घटना चुनें।


0

इसे आज़माएँ: कक्षा में MyHttpModule घोषणा करें:

private HttpApplication contextapp;

फिर:

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

और इसलिए, एक ही कक्षा में एक अन्य विधि (घटना) में:

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");
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.