سؤال

يمكنني حقًا تحديث متغيرات جلسة المستخدم من داخل HTTPModule الخاص بي، ولكن مما أستطيع رؤيته، هذا غير ممكن.

تحديث: الكود الخاص بي يعمل حاليًا داخل ملف OnBeginRequest () معالج الحدث.

تحديث: بعد النصيحة التي تلقيتها حتى الآن، حاولت إضافة هذا إلى Init () الروتين في HTTPModule الخاص بي:

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

ولكن في بلدي OnPreRequestHandlerExecute الروتينية، حالة الجلسة لا تزال غير متاحة!

شكرا، وأعتذر إذا فاتني شيء!

هل كانت مفيدة؟

المحلول

وجدت أكثر من هذا على المنتديات 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,
// regradless 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; }
      }
   }
}

نصائح أخرى

HttpContext.Current.Session يجب أن تعمل فقط، بافتراض أن وحدة HTTP الخاصة بك لا تتعامل مع أي منها أحداث خط الأنابيب التي تحدث قبل تهيئة حالة الجلسة ...

تحرير، بعد التوضيح في التعليقات:عند التعامل مع حدث طلب البدء, ، سيظل كائن الجلسة خاليًا/لا شيء، حيث لم تتم تهيئته بواسطة وقت تشغيل ASP.NET حتى الآن.للتغلب على هذه المشكلة، قم بنقل تعليمات المعالجة البرمجية الخاصة بك إلى حدث يقع بعد ذلك PostAcquireRequestState -- انا يعجبني PreRequestHandlerExecute لذلك بنفسي، نظرًا لأن جميع الأعمال ذات المستوى المنخفض يتم إنجازها إلى حد كبير في هذه المرحلة، لكنك لا تزال تستبق أي معالجة عادية.

والوصول إلى HttpContext.Current.Session في IHttpModule يمكن القيام به في معالج PreRequestHandlerExecute.

على PreRequestHandlerExecute : ل". يحدث فقط قبل بدء ASP.NET تنفيذ معالج حدث (على سبيل المثال، صفحة أو خدمة ويب XML)" وهذا يعني أن أمام "ASPX" صفحة يتم تقديم يحصل على تنفيذ هذا الحدث. "الدولة جلسة" متاح حتى تتمكن من ضرب نفسك.

مثال:

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

إذا كنت تكتب، HttpModule الأساسي العادي في تطبيق المدارة التي تريد تطبيق لطلبات asp.net من خلال صفحات أو معالجات، لديك فقط للتأكد من أنك تستخدم حدث في دورة حياة بعد إنشاء جلسة . PreRequestHandlerExecute بدلا من Begin_Request عادة أين أذهب. MDB ديه ذلك الحق في كتابه تحرير.

والتعليمات البرمجية المتكررة أطول المدرجة أصلا كما الإجابة على أعمال السؤال، ولكن غير معقدة وأوسع من السؤال الأول. وسوف تعامل مع الحالات التي يكون فيها محتوى يأتي من شيء لم يكن لديك معالج ASP.net متاحة حيث يمكنك تنفيذ واجهة IRequiresSessionState، وبالتالي التسبب في آلية جلسة لجعلها متاحة. (مثل gif ملف ثابت على القرص). انها في الأساس وضع معالج وهمية ثم ان تنفذ فقط تلك الواجهة لجعل الدورة المتاحة.

إذا كنت ترغب فقط في الدورة لرمز، ما عليك سوى اختيار الحدث المناسب للتعامل في الوحدة النمطية الخاصة بك.

جرب ما يلي: في فئة تعلن 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");
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top