2014-05-09 5 views
19

Ich hatte ein bisschen Code, den ich für ASP.NET und SignalR duplizierte, und ich beschloss, es als OWIN-Middleware neu zu schreiben, um diese Duplizierung zu entfernen.Kann OWIN Middleware die http Sitzung verwenden?

Sobald ich es ausgeführt habe, bemerkte ich, dass HttpContext.Current.Session war null, und ich habe keine Sitzung Objekt auf der , dass meine Middleware hat.

Ist es möglich, von OWIN aus auf die HTTP-Sitzung zuzugreifen?

Antwort

24

Ja, aber es ist ein ziemlicher Hack. Es wird auch nicht mit SignalR funktionieren, da SignalR vor dem Erwerb der Sitzung ausgeführt werden muss, um lange Sitzungssperren zu verhindern.

Sie diese Sitzung für jede Anfrage aktivieren:

public static class AspNetSessionExtensions 
{ 
    public static IAppBuilder RequireAspNetSession(this IAppBuilder app) 
    { 
     app.Use((context, next) => 
     { 
      // Depending on the handler the request gets mapped to, session might not be enabled. Force it on. 
      HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
      httpContext.SetSessionStateBehavior(SessionStateBehavior.Required); 
      return next(); 
     }); 
     // SetSessionStateBehavior must be called before AcquireState 
     app.UseStageMarker(PipelineStage.MapHandler); 
     return app; 
    } 
} 

Dann Sie die Sitzung mit entweder HttpContext.Current.Session oder

HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
+2

Meine Sitzung ist immer noch null. Was kann das verursachen? – Rastko

+0

Das gleiche hier, es ist immer noch 'null' !! – gdmanandamohon

5

ein Remix von the initial answer, so der Kern Diese Antwort ist zugreifen es sollte @Tratcher zugeschrieben werden. Es ist jedoch anders genug, es separat zu posten, anstatt eine Bearbeitung vorzuschlagen.


Angenommen, Sie eine kleine OWIN App für grundlegende Testzwecken machen wollen (zB als Stummel/Fälschung für eine größere API, wenn Integrationstests tun), einschließlich einer leicht hakish Weise Sitzungsstatus verwenden würde gut funktionieren .

Erstens, müssen Sie diese:

using Microsoft.Owin; 
using Microsoft.Owin.Extensions; 
using Owin; 

Mit denen können Sie eine Hilfsmethode erstellen:

public static void RequireAspNetSession(IAppBuilder app) 
{ 
    app.Use((context, next) => 
    { 
     var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
     httpContext.SetSessionStateBehavior(SessionStateBehavior.Required); 
     return next(); 
    }); 

    // To make sure the above `Use` is in the correct position: 
    app.UseStageMarker(PipelineStage.MapHandler); 
} 

Man könnte auch, dass als Erweiterung Methode erstellen, wie die ursprüngliche Antwort tat .

Beachten Sie, dass, wenn Sie nicht die UseStageMarker verwenden würde dieser Fehler auftritt:

Server Error in '/' Application.
'HttpContext.SetSessionStateBehavior' can only be invoked before 'HttpApplication.AcquireRequestState' event is raised.

Auf jeden Fall mit den oben genannten Sie jetzt in Ihrem Httpcontext OWIN App wie diese verwenden:

public void Configuration(IAppBuilder app) 
{ 
    RequireAspNetSession(app); 

    app.Run(async context => 
    { 
     if (context.Request.Uri.AbsolutePath.EndsWith("write")) 
     { 
      HttpContext.Current.Session["data"] = DateTime.Now.ToString(); 
      await context.Response.WriteAsync("Wrote to session state!"); 
     } 
     else 
     { 
      var data = (HttpContext.Current.Session["data"] ?? "No data in session state yet.").ToString(); 
      await context.Response.WriteAsync(data); 
     } 
    }); 
} 

Wenn Sie IIS Express mit dieser kleinen App anwerfen müssen Sie zuerst erhalten:

No data in session state yet.

Dann, wenn Sie zu http://localhost:12345/write gehen erhalten Sie:

Wrote to session state!

Dann, wenn Sie auf diesem Host auf andere URL zurück/Geht Sie erhalten:

11/4/2015 10:28:22 AM

oder etwas ähnliches.

+4

'System.Web.HttpContext.Current.Sitzung ist in *** OnResponseSignIn *** -Methode null. Code: 'Provider = neuer CookieAuthenticationProvider() { OnResponseSignIn = asynchroner Kontext =>' – Kiquenet