2014-05-09 2 views
19

J'avais un peu de code que je dupliquais pour ASP.NET et SignalR et j'ai décidé de le réécrire comme middleware OWIN pour supprimer cette duplication.Le middleware OWIN peut-il utiliser la session http?

Une fois que je l'ai exécuté, j'ai remarqué que HttpContext.Current.Session était nul, et je n'ai vu aucun objet de session sur le IOwinContext que mon middleware a.

Est-il possible d'accéder à la session http depuis OWIN?

Répondre

24

Oui, mais c'est un bidouillage. Cela ne fonctionnera pas non plus avec SignalR car SignalR DOIT s'exécuter avant l'acquisition de la session pour éviter les longs verrouillages de session.

Pour ce faire, pour permettre à la session pour toute demande:

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

Ensuite, vous pouvez accéder à la session soit HttpContext.Current.Session ou

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

Ma session est toujours nulle. Qu'est-ce qui peut causer ça? – Rastko

+0

Même ici, c'est toujours "nul" !! – gdmanandamohon

5

Cette réponse est un remix de the initial answer, de sorte que l'essentiel de il devrait être attribué à @Tratcher. Il est cependant assez différent de l'afficher séparément au lieu de suggérer une modification.


Supposant que vous voulez faire une petite application OWIN à des fins de test de base (par exemple, comme un talon/faux pour une plus grande API lors de faire des tests d'intégration), y compris d'une manière légèrement hakish d'utiliser l'état de session fonctionnerait très bien .

Tout d'abord, vous avez besoin de ces:

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

Avec ceux que vous pouvez créer une méthode d'assistance:

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

Vous pouvez aussi créer que comme une méthode d'extension comme la réponse initiale a .

Notez que si vous n'utilisez pas le UseStageMarker vous rencontrez cette erreur:

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

Dans tous les cas, avec ce qui précède, vous pouvez maintenant utiliser HttpContext dans votre application OWIN comme ceci:

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

Si vous lancez IIS express avec cette petite application vous obtenez d'abord:

No data in session state yet.

Alors si vous allez à http://localhost:12345/write vous obtiendrez:

Wrote to session state!

Alors si vous revenez/aller à tout autre URL sur cet hôte, vous obtiendrez:

11/4/2015 10:28:22 AM

ou quelque chose de similaire.

+4

'System.Web.HttpContext.Current.Session' est null dans la méthode *** OnResponseSignIn ***. Code: 'Fournisseur = new CookieAuthenticationProvider() { OnResponseSignIn = contexte asynchrone =>' – Kiquenet

Questions connexes