原本去年在做項目時,寫好的一記篇博客分享給大家。
Asp.net頁面跳轉Session丟失問題
編寫人:CC阿爸
2014-4-2
l 近來在做泛微OA與公司自行開發的系統集成登錄的問題。在使用Response.redirect跳轉時,Session變量會丟失的問題。
經過在網上搜索部分解決方案,大致可以歸類為以下幾種情況
- 是因為iis回收的原因。有人建議更改session存儲模式
改變session的存儲介質,默認為Inproc,還有另外兩種方式,StateServer和SQLServer。
這里把mode改為StateServer,默認的inproc雖然方便好用,但是非常容易出現session丟失的問題,
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="20" stateNetworkTimeout="10"/>
- IE6/IE7支持的P3P(Platform for Privacy Preferences Project (P3P) specification)協議默認阻止第三方無隱私安全聲明的cookie,Firefox目前還不支持P3P安全特性,firefox中自然也不存 在此問題了。Mircosoft對此的具體描述可以參見 Privacy in Internet Explorer 6
解決辦法是在服務器響應時輸出P3P的主機頭聲明:
if (context.Request.Browser.Browser.ToUpper().Contains("IE"))
context.Response.Headers.Add("P3P", "CP=CAO PSA OUR");
- 當頁面中是否了frameset,發現在每個frame中顯示頁面的SessionID在第一次請求時都不相同,原因是你的frameset是放在一個htm頁面上而不是ASPX頁面。
在一般情況下,如果frameset是aspx頁面,當你請求頁面時,它首先將請求發送到Web服務器,此時已經獲得了SessionID,接着瀏覽器會分別請求Frame中的其他頁面,這樣所有頁面的SessionID就是一樣的,就是FrameSet頁面的SessionID。
然而如果你使用Html頁面做FrameSet頁面,第一個請求將是HTML頁面,當該頁面從服務器上返回是並沒有任何Session產生,接着瀏覽器會請求Frame里面的頁面,這樣這些頁面都會產生自己的SessionID,所以在這種情況下就會出現這種問題。當你重新刷新頁面時,SessionID就會一樣,並且是最后一個請求頁面的SessionID。
綜上發現,我使用的是第三種,因此常會出現session丟失的問題,使用第一二種解決方法未能解決。
於是仔細觀察了httpwatch中截獲的請求,發現Cookies選項中在跳轉之前是空的,這個里面應該存儲了當前session的id才對,於是就想如果我在Redirect之前就將session的id放到Cookies中是不是就能解決這個問題了呢。果然不出所料,修改完后問題解決了。
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", Session.SessionID));
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", Session.SessionID));
Response.Redirect("index.htm",false);
后來想到,這個問題還有一個比較簡單的解決辦法就是:
Server.Transfer("index.htm ")