繼上回將.Net開發好的功能成功建置於運行中的網站後,
http://Jerry5217.pixnet.net/blog/post/249657751

這回又遇到了一個狀況!
該網站依照使用者登入帳號來做功能選單的控管,
跟其他網站一樣最常用的當然就是利用Session了,
但是登入網站的頁面是最早用VB Script開發的,
而我是在.Net的平台上開發的新功能,
經過了前幾回合的折騰才讓新功能正確的開始運行,
結果發現在成功登入後設定的Session內容,
用C#.Net開發的網頁讀取不到,它竟然消失了!

可是如果不關閉瀏覽器,回到上一頁然後重新整理,
Session的內容是存在的,如果再一次進入.Net開發的網頁依舊抓不到!

所以整個網站包含早期ASP 3.0以及現在ASP.Net所開發的網頁功能:

又花了幾天的時間Google了一下,再寫幾個網頁反覆測試了幾次,
原來跨平台之間的Session是不能互通的,這會不會是IIS7.0新的設定呢?
以前從IIS5.0玩到IIS6.0,網站一路開發下來也是不同平台共處,
Session只要設定一次就大家共用了(除非是ViewState),但現在卻是不行了…

所以我另外做了一個解決方案:
1)用原本就熟悉的VB Script撰寫一隻程式將Session內容新增暫存於資料表
2)轉址進.Net網頁後,從資料表擷取並重新設定Session,然後隨即刪除資料表內容
這個網頁轉址的動作,進行了對資料庫的各一次的新增及刪除行為,
使用者在使用上不會察覺任何異狀,簡單流程示意圖修正如下:

不同的使用者有不同的Session內容,但是程式碼是讀取同一個名稱的Session,
例如:路人甲的Session("ID")="A1"而路人乙的Session("ID")="B2",
網頁中設定Session的名稱都是"ID",但是Session的內容就會因人而異了,
所以要將每個連線使用者的Session內容,先存入資料表再正確無誤的讀取出來,
就要神不知鬼不覺的再偷設一個不重複的Key,然後從上述的步驟1傳到步驟2,

資料表設計如下:

  PageDataConverter
  PageKey nvarchar(10)
  Title nvarchar(10)
  Body nvarchar(10)

資料表名稱:PageDataConverter
欄位PageKey:存放轉址時不重複的Key值
欄位Title:存放Session的名稱
欄位Body:存放該Session名稱的內容

當使用者點選功能表的項目,進入.Net開發的網頁功能時...
步驟1:程式碼用VB Script撰寫,讀取Session產生PageKey存入資料庫,
假設許多人同時連線這個網站,要分別自動產生不能重複的PageKey,
我利用"秒"這個單位風險應該夠低了吧!程式碼如下:

    PageKey = Replace(Timer,".","")
    Title = "ID"
    Body = Session("ID")

利用VB Script的時間指令"Timer"取得自午夜12:00到現在當下的秒數,
Timer這個指令會回傳小數點到第2位數的秒數值,
我用Replace指令直接把小數點拿掉,這一串數字在當下應該很難重複了!
將上列三組資料存入資料庫後,執行網頁轉址到步驟2:

     Response.Redirect("../ASP_Net_WebPage/PageDataConverter.aspx?P=" & PageKey)

步驟2在.Net的環境中解析網址讀取到PageKey的內容,

     string PK = "";
     if (Request.Url.Query != "")
     {
         PK = Request.Url.Query;
         PK = PK.Substring(PK.IndexOf("P=") + 2);
     }

然後連線資料庫取得Session名稱及內容後,重新於網頁中設定Session,

     string SQLCom1 = "";
     SQLCom1 = "select * from PageDataConverter where PageKey='" + PK + "'";
     SqlCommand cmdSQL1 = new SqlCommand(SQLCom1, cnSQL1);
     SqlDataReader DR1 = cmdSQL1.ExecuteReader();
     if (DR1.Read())
         Session[DR1["Title"].ToString()] = DR1["Body"].ToString();

     DR1.Close();
     DR1.Dispose();
     cmdSQL1.Dispose();

最後別忘了將資料刪除喔!

       SQLCom1 = "Delete PageDataConverter where PageKey='" + PK + "'";
       SqlCommand cmdSQL2 = new SqlCommand(SQLCom1, cnSQL1);
       int i = 0;
       i = cmdSQL2.ExecuteNonQuery();
       cmdSQL2.Dispose();

由於在步驟1所利用的Timer指令是從每天的午夜12:00開始起算,
所以步驟2讀取並設定完Session後,將資料刪除的動作就格外重要了!
除了可避免資料讀取錯誤,更能確保Session資料不會被盜用!

經過上述的規劃等於是增加一個進入.Net網頁前的步驟,
目的是讓不同開發平台的網頁都擁有相同的Session設定,
這樣在關連到後端同一個資料庫時,就開發而言是會比較單純的,

可是不同開發平台的Session設定就算用了一樣的名稱及內容,
在同一個IIS的網站中是否也代表一樣呢?
可能就要花時間再多專研一下了...

 

arrow
arrow

    王振權 發表在 痞客邦 留言(0) 人氣()