2008-10-20 94 views
41

沒有路由,HttpContext.Current.Session在那裏,所以我知道StateServer正在工作。當我路由我的請求時,HttpContext.Current.Session在路由頁面中是null。我在IIS 7.0上使用.NET 3.5 sp1,沒有MVC預覽。看來AcquireRequestState在使用路由時永遠不會被觸發,因此session變量沒有實例化/填充。HttpContext.Current.Session在路由請求時爲空

當我嘗試訪問會話變量,我得到這個錯誤:

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>.

調試時,我也得到了錯誤的HttpContext.Current.Session是不是在這方面進行訪問。

-

web.config看起來是這樣的:

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

這裏的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; 
    } 
} 

我也試圖把EnableSessionState="True"在aspx頁面的頂部但仍然沒有。

任何見解?我應該寫另一個執行IRequiresSessionStateHttpRequestHandler嗎?

謝謝。

回答

52

明白了。其實很愚蠢。它的工作之後,我刪除&添加SessionStateModule像這樣:

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

簡單地增加,因爲「會話」應已在machine.config定義它不會工作。

現在,我不知道這是否是通常的事情。它似乎並不如此,因爲它看起來很粗糙...

+3

非常感謝。它很好地解決了我的問題 - 事實證明,生產服務器需要它,但不是開發機器。 – Raithlin 2010-02-03 07:42:04

+2

這是ins @ ne!謝謝。這固定了我的「TempData」(mvc剃鬚刀)值也從消失(因爲TempData使用會話)。聖莫里。 – granadaCoder 2015-08-10 20:44:52

+0

我有TempData值消失的問題,但這並沒有解決它。 – Dinei 2015-08-27 19:54:12

0

您似乎忘記了在config文件中添加狀態服務器地址。

<sessionstate mode="StateServer" timeout="20" server="127.0.0.1" port="42424" /> 
+1

試過但仍然是相同的。它應該無關緊要其默認值:「tcpip = loopback:42424」(http://msdn.microsoft.com/en-us/library/system.web.configuration.sessionstatesection.stateconnectionstring.aspx) 我懷疑問題出在Session提供程序中,因爲它沒有路由工作。 – Loki 2008-10-20 11:32:00

0

配置節似乎聽起來很好,因爲它的工作原理如果頁面正常訪問。我嘗試了其他配置建議,但問題仍然存在。

我懷疑問題是在會話提供程序,因爲它沒有路由工作。

2

什麼@博格丹馬克西姆說。或者如果您不使用外部sesssion狀態服務器,則更改爲使用InProc。

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

有關SessionState指令的更多信息,請參閱here

+0

如果我正常訪問頁面,SessionState將有效。如果我使用路由,HttpContext.Current.Session爲空。 部分似乎在配置中工作。 – Loki 2008-10-20 11:41:26

0

我認爲這部分代碼會對上下文進行更改。

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

而且這部分代碼是沒用的:

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

總是返回頁面枯萎這是空或不是。

+0

謝謝你提醒我。在嘗試了很多東西之後,這是一些退化的代碼。 :D – Loki 2008-10-21 09:03:48

3

幹得好!我一直有完全相同的問題。添加和刪​​除會話模塊對我來說也很完美。但是它並沒有被HttpContext.Current.User帶回來,所以我嘗試了一下FormsAuth模塊的小技巧,果然,它做到了。

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

只需在web.config中添加屬性runAllManagedModulesForAllRequests="true"system.webServer\modules

此屬性在MVC和動態數據項目中默認啓用。

1

一個更好的解決方案是

runAllManagedModulesForAllRequest是一個聰明的事情尊重刪除和resinserting會話模塊。

alk。

14

runAllManagedModulesForAllRequests=true實際上是一個真正的不好的解決方案。這將我的應用程序的加載時間增加了200%。更好的解決方案是手動刪除和添加會話對象,並避免將所有託管模塊全部運行在一起。

0

我錯過了會議適配器System.web.mvc DLL的引用,並添加相同的固定的問題。

希望它能幫助別人度過相同的情景。

1

上述解決方案都不適用於我。我將以下方法添加到global.asax.cs然後會話不爲空:

protected void Application_PostAuthorizeRequest() 
{ 
    HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required); 
}