2014-05-09 21 views
19

Miałem trochę kodu, który kopiowałem dla ASP.NET i SignalR i postanowiłem przepisać go jako oprogramowanie pośredniczące OWIN, aby usunąć to duplikowanie.Czy oprogramowanie pośrednie OWIN może korzystać z sesji http?

Po uruchomieniu zauważyłem, że HttpContext.Current.Session ma wartość NULL i nie widzę żadnego obiektu sesji na IOwinContext, który ma moje oprogramowanie pośrednie.

Czy można uzyskać dostęp do sesji http z OWIN?

Odpowiedz

24

Tak, ale to dość hack. Nie będzie też działać z SignalR, ponieważ SignalR MUSI uruchomić przed sesją, aby zapobiec długotrwałym blokadom sesji.

Czy to aby umożliwić sesji dla każdego żądania:

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; 
    } 
} 

Następnie można otworzyć sesję albo HttpContext.Current.Session lub

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

Moja sesja jest nadal pusta. Co może to spowodować? – Rastko

+0

To samo tutaj, nadal jest 'null' !! – gdmanandamohon

5

Ta odpowiedź jest remix od the initial answer, więc sedno należy go przypisać do @Tratchera. Jest jednak na tyle różne, by opublikować go osobno zamiast sugerować zmianę.


Przypuśćmy chcesz zrobić mały OWIN aplikację dla podstawowych celów testowych (np jako zalążek/fałszywe dla większego API robiąc testy integracyjne), w tym lekko hakish sposób wykorzystania stanu sesji będzie działać dobrze .

Najpierw trzeba te:

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

Z tych można utworzyć metody pomocnika:

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

Można również utworzyć, że jako metodę rozszerzenia jak oryginał odpowiedź zrobił .

Należy pamiętać, że jeśli nie będzie używać UseStageMarker wystąpienia tego błędu:

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

W każdym razie z powyższego można teraz używać HttpContext w swojej aplikacji OWIN tak:

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

Jeśli odpalić IIS Express, z tej małej aplikacji musisz najpierw dostać:

No data in session state yet.

Następnie jeśli pójdziesz do http://localhost:12345/write dostaniesz:

Wrote to session state!

Następnie, jeśli wrócisz/przejść do innego adresu URL na tym hoście dostaniesz:

11/4/2015 10:28:22 AM

lub coś podobnego.

+4

'System.Web.HttpContext.Current.Sesja' ma wartość NULL w metodzie *** OnResponseSignIn ***. Kod: 'Provider = new CookieAuthenticationProvider() { OnResponseSignIn = asynchroniczny kontekst => – Kiquenet