HttpContext.Current.Session è nullo durante il routing delle richieste
-
03-07-2019 - |
Domanda
Senza routing, HttpContext.Current.Session
è lì, quindi so che StateServer
funziona. Quando instrado le mie richieste, null
è AcquireRequestState
nella pagina indirizzata. Sto usando .NET 3.5 sp1 su IIS 7.0, senza le anteprime MVC. Sembra che 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>.
non venga mai attivato quando si utilizzano le route e quindi la variabile di sessione non viene istanziata / riempita.
Quando provo ad accedere alle variabili Session, ottengo questo errore:
web.config
Durante il debug, visualizzo anche l'errore che EnableSessionState="True"
non è accessibile in quel contesto.
-
Il mio HttpRequestHandler
è simile al seguente:
<configuration>
...
<system.web>
<pages enableSessionState="true">
<controls>
...
</controls>
</pages>
...
</system.web>
<sessionState cookieless="AutoDetect" mode="StateServer" timeout="22" />
...
</configuration>
Ecco l'implementazione di IRouteHandler:
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;
}
}
Ho anche provato a mettere IRequiresSessionState
nella parte superiore delle pagine di aspx ma ancora niente.
Qualche intuizione? Dovrei scrivere un altro <=> che implementa <=>?
Grazie.
Soluzione
Capito. Abbastanza stupido, in realtà. Ha funzionato dopo aver rimosso l'amplificatore &; aggiunto il SessionStateModule in questo modo:
<configuration>
...
<system.webServer>
...
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
...
</modules>
</system.webServer>
</configuration>
La semplice aggiunta non funzionerà poiché " Sessione " avrebbe dovuto essere già stato definito in machine.config
.
Ora, mi chiedo se questa è la solita cosa da fare. Sicuramente non sembra così dato che sembra così rozzo ...
Altri suggerimenti
Aggiungi l'attributo runAllManagedModulesForAllRequests="true"
a system.webServer\modules
in web.config.
Questo attributo è abilitato per impostazione predefinita nei progetti MVC e Dynamic Data.
runAllManagedModulesForAllRequests=true
è in realtà una vera cattiva soluzione. Ciò ha aumentato del 200% il tempo di caricamento della mia applicazione. La soluzione migliore è rimuovere e aggiungere manualmente l'oggetto sessione ed evitare l'attributo tutti i moduli gestiti tutti insieme.
Nessuna di queste soluzioni ha funzionato per me. Ho aggiunto il seguente metodo in global.asax.cs
quindi Session non era null:
protected void Application_PostAuthorizeRequest()
{
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}
Bel lavoro! Ho avuto lo stesso identico problema. L'aggiunta e la rimozione del modulo Session ha funzionato perfettamente anche per me. Tuttavia, non è stato riportato da HttpContext.Current.User, quindi ho provato il tuo piccolo trucco con il modulo FormsAuth e abbastanza sicuro, l'ho fatto.
<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
Cosa ha detto @Bogdan Maxim. O cambia per usare InProc se non stai usando un server di stato sesssion esterno.
<sessionState mode="InProc" timeout="20" cookieless="AutoDetect" />
Cerca qui per maggiori informazioni sulla direttiva SessionState.
La sezione di configurazione sembra sana poiché funziona se si accede normalmente alle pagine. Ho provato le altre configurazioni suggerite ma il problema è ancora lì.
Dubito che il problema sia nel fornitore della sessione poiché funziona senza il routing.
Penso che questa parte del codice apporti modifiche al contesto.
Page page = BuildManager.CreateInstanceFromVirtualPath(
m_VirtualPath,
typeof(Page)) as Page;// IHttpHandler;
Anche questa parte del codice è inutile:
if (page != null)
{
return page;
}
return page;
Restituirà sempre la pagina in cui è nullo o meno.
una soluzione migliore è
runAllManagedModulesForAllRequests è una cosa intelligente da fare rispetto a rimuovere e reinserire il modulo di sessione.
alk.
Mi mancava un riferimento alla dll System.web.mvc nell'adattatore di sessione e l'aggiunta della stessa risolto il problema.
Speriamo che possa aiutare qualcun altro a superare lo stesso scenario.