1. 程式人生 > >記錄一次Session偶爾獲取不到的解決過程

記錄一次Session偶爾獲取不到的解決過程

導讀

平臺下某子系統有密碼登入需求,初步考慮用Session,登入後設置Session[key]=value;Session中若某key對應的Session,即Session[key]為null則限制操作。對應所用技術點:Asp.Net MVC & Razor 檢視引擎,技術點較簡單,雖然走了一些彎路,但加深了對Session的理解。

一、前臺ajax校驗輸入密碼正確性

$.ajax({
            url: "@Url.Action("CheckPwd","Earnings")",
                type: "post",
                data: { "pwd": pwd},
                beforeSend: function () {
                    loadingLayer = layer.load(1, {
                        shade: [0.6, '#fff']
                    });
                },
                success: function (data) {
                    var result = JSON.parse(data);
                    if (result.Success) {
                       //頁面跳轉
                    }
                    else {
                       //
                    }
                },
                complete: function (XMLHttpRequest, textStatus) {
                  //
                }
            });
        }

二、後臺Action 校驗密碼輸入正確後,設定Session["EarningsManagePwd"] 

public ActionResult CheckPwd(string pwd)
        {
            if (//)
            {
                Session["EarningsManagePwd"] = encryptPwd;
            }
            return Json();
        }

三、在其他頁面,未登入沒有訪問許可權時,跳轉到登入頁,後臺Action核心程式碼如下:

if (Session["EarningsManagePwd"] == null || string.IsNullOrEmpty(Session["EarningsManagePwd"].ToString()))
            {
                return RedirectToAction("Index");
            }

四、出現問題,Session值時而獲取不到

  • 做的一些demo,簡單使用Session,沒有發現異常;
  • 本地除錯沒發現什麼問題,釋出到伺服器後,發現Session["EarningsManagePwd"]的值時而獲取不到,變為null,操作頁面時總跳轉到登入頁,多次操作中偶爾會獲取到Session值,達到預期效果;
  • 然而這樣的效果堅決不能容忍,勢必找尋其根源,探究哪裡出了問題;

五、查詢解決方案歷程

 1.略過一系列除錯步驟及“不對症的藥方”,懷疑System.Web.HttpContext.Current.Session與MVC下Session二者的區別

(1)MVC下Session轉到定義

(2)System.Web.HttpContext.Current.Session轉到定義

兩者是同一個類,似乎沒有本質區別

(3)做相容處理,判斷二者的值,二者也是同一個值,仍舊時而獲取不到值,時而獲取到

(4)HttpContext.Current.Session 和 Session 的區別(後話)

They're effectively the same, in that they will access the same Session data.

他們具有相同的作用,他們將會訪問相同的session資料。

The reason you can call Session in your code-behind is because ASP.Net pages by default extend the System.Web.UI.Page type. This has a Session public property. If you look at the code for this in Reflector you can see that it just calls HttpContext.Current.Session itself (through its own Contextproperty).

在你的code-behind程式碼中之所以能夠呼叫session,是因為Asp.net的頁面預設是繼承自system.web.ui.page型別的。這個型別有一個名字為session的公共屬性。如果你在Reflector反編譯軟體中檢視這個公共屬性的程式碼,你會看到這個屬性自己僅僅是呼叫的httpcontext.current.session而已。(在他自己的 Context屬性中也全部是這樣使用的)

In other classes you will not have access to that property, but you can use HttpContext.Current.Session to access the session data instead, as long as you're running in the context of a web application.

在其他的類中,你可能不可以直接訪問system.web.ui.page的session屬性,但是你能夠用httpcontext.current.session來訪問session資料,只要你的程式碼正執行在一個web應用程式的上下文中。

2.查詢到可以通過更改Web.config檔案中sessionState節點配置來解決

我們在用C#開發程式的時候經常會遇到Session很不穩定,老是資料丟失。下面就是Session資料丟失的解決辦法希望對您有好處。

1、在WEB.CONFIG檔案中修改SESSION狀態儲存模式,如:<sessionState mode='StateServer' stateConnectionString='tcpip=127.0.0.1:42424' sqlConnectionString='data source=127.0.0.1;Trusted_Connection=yes' cookieless='true' timeout='180'/> 

2、啟動系統服務“ASP.NET狀態服務 ”,系統預設是手動啟動的 

3、如果SESSION中儲存的資料型別是自定義的,如結構,請在自定義資料型別處序列化會話狀態,即在類或結構申明前加[Serializable] 

啟動Asp.Ner State Service

將web.config檔案中sessionState節點替換為”<sessionState mode='StateServer' stateConnectionString='tcpip=127.0.0.1:42424' sqlConnectionString='data source=127.0.0.1;Trusted_Connection=yes' cookieless='true' timeout='180'/> ”,Session["EarningsManagePwd"]取值正常,達到預期效果,然而出現了新的問題,瀏覽器位址列莫名多瞭如下一串字串,每個連結地址下都多了類似的字串

多餘字串

session標識兩種方式儲存:
  1)cookieless=false,預設方式,sessionId存放在cookie
  2)cookieless=true,sessionId存放在url

常用的sessionstate模式:
1.inProc模式:受IIS程序影響,容易丟失,但是也正因如此,是唯一支援Session_OnEnd 事件的模式;
2.StateServer模式 :提供獨立的狀態服務,即使web應用程式重啟,會話仍然保持;
3.SQLServer 模式:利用sqlserver提供狀態儲存,即使web應用程式重啟,會話仍然保持,
   並且,利用故障轉移叢集,可以讓其他sqlserver接管故障服務,而不會丟失session

將web.config檔案中sessionState節點cookieless屬性值改為false,位址列sessionId果然消失了!

(3)優化sessionState 配置節點(暫不考慮Session叢集共享)

<sessionState mode="StateServer" ></sessionState>

附其他參考資料

總結

解決Session偶爾獲取不到的方法

1.web.config檔案中sessionState節點mode屬性由預設的InProc改為StateServer;

2.啟動服務Asp.Net State Service;

3.如果Session中儲存的資料型別是自定義的,如結構,請在自定義資料型別處序列化會話狀態,即在類或結構申明前加[Serializable] ;