[ASP.NET] 紀錄使用者關閉視窗 in MasterPage

有時候,總會有一些情況下,會被要求說要記錄下來使用者登入登出的一些資訊,
登入登出之類的,在Asp.Net中只要抓出一些對應的事件,之後要記錄下來都算好做。

然而當連使用者直接關閉視窗時,也要記錄下來的時候,就比較麻煩了點點,
因為這些動作畢竟是屬於client的事情,還好的是這樣的需求網路上也是有一些可以參考的,

但碰到了MasterPage的時候.....

有時候,總會有一些情況下,會被要求說要記錄下來使用者登入登出的一些資訊,
登入登出之類的,在Asp.Net中只要抓出一些對應的事件,之後要記錄下來都算好做。

然而當連使用者直接關閉視窗時,也要記錄下來的時候,就比較麻煩了點點,
因為這些動作畢竟是屬於client的事情,還好的是這樣的需求網路上也是有一些可以參考的,

例如 [ASP.NET]記錄使用者登入登出時間 by 小毛,寫過這篇文章。
利用Javascript的方式,在關閉頁面時,利用XMLHTTP Post到另一個頁面,
在這個頁面做資料的紀錄。

下面是基本的Code (此Sample來自於 藍色小舖的發問,由Gipi大回覆的)

   1:     <script type="text/javascript" language="javascript">
   2:      window.onunload = CloseWindows; 
   3:      function CloseWindows() 
   4:      { 
   5:          //按下X關閉 
   6:          if (event.clientY < 0) 
   7:          { 
   8:                   try 
   9:                   {    
  10:                       var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");  
  11:                       //使用者自行關閉視窗時
  12:                       xmlhttp.open("POST","CloseWindows.aspx", false); 
  13:                       xmlhttp.send();  
  14:                       return true; 
  15:                  } 
  16:                  catch(e) 
  17:                  { 
  18:                       alert('close windows error message:' + e.message); 
  19:                  } 
  20:          } 
  21:      }     
  22:      </script>

 

指到CloseWindows.aspx後,就可以在裡面,例如 Page_Load 的地方想怎麼紀錄就怎麼紀錄啦!!

 

然而事情真的這麼美好嗎? 凡事不可能就這樣剪剪貼貼就完成的!!!

同樣的,我也碰到了這樣的問題,
由於我有使用到MaterPage
如果有些頁面是在一些目錄底下的話,他會找不到CloseWindows.aspx的頁面,
狀況例如..

http://test.com/First.aspx (in MasterPage)
http://test.com/floder/Second.aspx (in MasterPage)

http://test.com/CloseWindows.aspx


參考了很多文章,

也有人提過說如果 MasterPage中引用Javascript路徑的問題,
像是這篇文章,是處理Javascript引用js的方法,
解決MasterPage中引用Javascript的路徑問題 by Roger

   1:  <script type="text/javascript" src="<%=ResolveClientUrl("~/js/jquery-1.2.6.min.js")%>"></script>

 

也嘗試著用這個方法去測試,但.....我失敗了。
之後也嘗試著想說用Javascript相對路徑去組合看看,但因為網站有可能會架在虛擬目錄上,或是其他的可能性,
所以我並沒有很順利地想到一個方法去組合出來,也或許是我對Javascript還不夠熟悉。

之後跟同事討教討論後,找到另一個workaround的方法,就是利用一個HiddenField去做一個橋梁,
然後再MasterPage  Page_Load  的時候,利用Request的方式去組合出我希望的樣子(畢竟也比較熟悉C#呀),
再丟進去,之後則是讓javascript利用document.getElementById去抓到HiddenField,
就成功達成啦。

Sample Code如下

MasterPage.aspx

   1:      <script type="text/javascript" language="javascript">
   2:          window.onunload = CloseWindows;
   3:          function CloseWindows() { 
   4:              //按下X關閉 
   5:              if (event.clientY < 0) {
   6:                  try { 
   7:                      var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
   8:                      //使用者自行關閉視窗時                     
   9:                      var url = document.getElementById("CloseWeb_URL").value;
  10:                      xmlhttp.open("POST", url, false);
  11:                      xmlhttp.send();
  12:                      return true;
  13:                  }
  14:                  catch (e) {
  15:                      alert('close windows error message:' + e.message);
  16:                  }
  17:              }
  18:          }  
  19:      </script>

 

   1:   <asp:HiddenField ID="CloseWeb_URL" runat="server" />  

 

MasterPage.aspx.cs

   1:      protected void Page_Load(object sender, EventArgs e)
   2:      {  
   3:          if (!IsPostBack)
   4:          { 
   5:              CloseWeb_URL.Value = GetCloseWeb(); 
   6:          }
   7:      }
   8:      private string GetCloseWeb()
   9:      {
  10:          string Path = Request.PhysicalPath.Replace(Request.PhysicalApplicationPath, "").Replace(@"\", @"/");
  11:          Path = Request.Url.ToString().Replace(Path, "") + "CloseWindows.aspx?url=" + Request.RawUrl;
  12:          //後面的 Request.RawUrl想抓到是在哪個頁面關閉了視窗
  13:          return Path;
  14:      }

 

之後導向到CloseWindows.aspx後,就看各自的需求,看要怎麼去做紀錄啦!!
完工!

如果有其他不錯的方法,也請告訴我,一起討論 ! 大感謝

參考整理

 


歡迎大家一起到MSDN學習與討論