48 votes

HttpContext.Current.Session est null lorsque les demandes de routage

Sans routage, HttpContext.Current.Session y est si je sais que l' StateServer travaille. Quand je voie mes demandes, HttpContext.Current.Session est null dans le acheminé page. Je suis à l'aide .NET 3.5 sp1 sur IIS 7.0, sans le MVC aperçus. Il semble que l' AcquireRequestState n'est jamais déclenché lors de l'utilisation de routes et donc la variable de session n'est pas instancié/rempli.

Lorsque j'essaie d'accéder aux variables de Session, j'ai cette erreur:

base {System.Runtime.InteropServices.ExternalException} = {"Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the <configuration>.

Pendant le débogage, j'ai aussi l'erreur que l' HttpContext.Current.Session n'est pas accessible dans ce contexte.

--

Mon web.config ressemble à ceci:

<configuration>
  ...
  <system.web>
    <pages enableSessionState="true">
      <controls>
        ...
      </controls>
    </pages>
    ...
  </system.web>
  <sessionState cookieless="AutoDetect" mode="StateServer" timeout="22" />
  ...
</configuration>

Voici la IRouteHandler mise en œuvre:

public class WebPageRouteHandler : IRouteHandler, IRequiresSessionState
{
    public string m_VirtualPath { get; private set; }
    public bool m_CheckPhysicalUrlAccess { get; set; }

    public WebPageRouteHandler(string virtualPath) : this(virtualPath, false)
    {
    }
    public WebPageRouteHandler(string virtualPath, bool checkPhysicalUrlAccess)
    {
        m_VirtualPath = virtualPath;
        m_CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        if (m_CheckPhysicalUrlAccess
            && !UrlAuthorizationModule.CheckUrlAccessForPrincipal(
                   m_VirtualPath,
                   requestContext.HttpContext.User,
                   requestContext.HttpContext.Request.HttpMethod))
        {
            throw new SecurityException();
        }

        string var = String.Empty;
        foreach (var value in requestContext.RouteData.Values)
        {
            requestContext.HttpContext.Items[value.Key] = value.Value;
        }

        Page page = BuildManager.CreateInstanceFromVirtualPath(
                        m_VirtualPath, 
                        typeof(Page)) as Page;// IHttpHandler;

        if (page != null)
        {
            return page;
        }
        return page;
    }
}

J'ai aussi essayé de mettre la EnableSessionState="True" sur le haut de la page aspx, mais encore, rien.

Des idées? Devrais-je écrire un autre HttpRequestHandler qui implémente IRequiresSessionState?

Merci.

55voto

Loki Points 621

Je l'ai. Assez stupide, en fait. Cela a fonctionné après que j'ai enlevé et ajouté le SessionStateModule comme ceci:

 <configuration>
  ...
  <system.webServer>
    ...
    <modules>
      <remove name="Session" />
      <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
      ...
    </modules>
  </system.webServer>
</configuration>
 

Le simple fait de l'ajouter ne fonctionnera pas, car "Session" devrait déjà avoir été défini dans les machine.config .

Maintenant, je me demande si c'est la chose habituelle à faire. Cela ne semble sûrement pas, puisqu'il semble si grossier ...

24voto

gandjustas Points 1451

Ajoutez simplement l'attribut runAllManagedModulesForAllRequests="true" à system.webServer\modules dans web.config.

Cet attribut est activé par défaut dans les projets MVC et Dynamic Data.

16voto

runAllManagedModulesForAllRequests=true est en réalité une très mauvaise solution. Cela a augmenté le temps de chargement de mon application de 200%. La meilleure solution consiste à supprimer et à ajouter manuellement l'objet de session et à éviter tous les attributs d'exécuter tous les modules gérés.

3voto

tvanfosson Points 268301

Ce que @Bogdan Maxim a dit. Vous pouvez également utiliser InProc si vous n’utilisez pas de serveur d’état de session externe.

 <sessionState mode="InProc" timeout="20" cookieless="AutoDetect" />
 

Regardez ici pour plus d’informations sur la directive SessionState.

3voto

Mike Points 80

Bon travail! J'ai eu exactement le même problème. Ajouter et supprimer le module Session a parfaitement fonctionné pour moi aussi. Il n’a toutefois pas été rapporté par HttpContext.Current.User, j’ai donc essayé votre petit tour avec le module FormsAuth et, bien sûr, vous y êtes parvenu.

 <remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X