常常被問到,ASP.NET 的應用程式是否可以共用 Session?我之前的答案一律是「不行」,但真的不行嗎?其實是可以的,只是很難實作。現在,應用 Windows Server AppFabric 的 Cache 功能,就可以達到這樣的境界。
環境
使用上次介紹的建立 AppFabric Cache Cluster,就可以建立起 Windows Server AppFabric 的環境。
測試網頁
首先,建立一個設定/讀取 Session 的網頁。網頁內容如下。
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Welcome to ASP.NET! SessionId = <%= Session.SessionID%>
</h2>
Set value:
<asp:TextBox runat="server" ID="txtValue" />
<asp:Button Text="Set Value" runat="server" ID="btnSet"
onclick="btnSet_Click" />
<br />
Read value:
<asp:Label Text="text" runat="server" ID="lblValue" />
<asp:Button Text="Read Value" runat="server" ID="btnRead"
onclick="btnRead_Click" />
<br />
</asp:Content>
而該頁的 CodeBehind 程式如下
using System;
namespace WebApplication3
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSet_Click(object sender, EventArgs e)
{
Session["value"] = txtValue.Text;
}
protected void btnRead_Click(object sender, EventArgs e)
{
lblValue.Text = (string)Session["value"];
}
}
}
很簡單的程式。按「Set Value」鍵時,將值寫到 Session中,而按「Read Value」鍵時,將值顯示到網頁上。
在 IIS 上,該Application 的名稱為 WebApplication3。以建立 Application 的方式,建立出使用相同路徑但不同應用程式名稱的 WebApplication4。如下圖

未使用 AppFabric 的 Cache 功能時
先打開 WebApplication3 的應用程式 Default.aspx 頁。輸入值為 aaa,再按 Read Value 鍵後,網頁會顯示剛剛輸入的值 aaa。

再打開 WebApplication4的網頁 Default.aspx 頁,按Read Value 鍵,網頁顯示值為空白。

請注意到,即使用相同的Application,不同的 SessionId代表不同的 session,當然會讀到不同的值。雖然是不同的 Application,但有可能有相同SessionId。為了讓測試有意義,此網頁故意將 SessionId 顯示出來。
使用 AppFabric 的 Cache 作為 ASP.NET 的 Session
將 Web.config 修改如下
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="dataCacheClient"
type="Microsoft.ApplicationServer.Caching.DataCacheClientSection,
Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"
allowLocation="true"
allowDefinition="Everywhere"/>
</configSections>
<dataCacheClient>
<hosts>
<host name="AppFabric1" cachePort="22233"/>
</hosts>
</dataCacheClient>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
<providers>
<add
name="AppFabricCacheSessionStoreProvider"
type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider"
cacheName="session" sharedId="MyApp"/>
</providers>
</sessionState>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
此後,如上一測試網頁動作再執行一次。發現可以共用 Session 了。


注意一下,sharedId="MyApp"/ 兩個應用程式都使用相同的 sharedId。如果不同,就是不同的 session 了.
結論
使用 Windows Server AppFabric 的 Cache 作為 ASP.NET 的 Session,除了享有高可用性(High Avaliability)外,也意外地擁有跟應用程式共用 Session 的效果。
但,這樣好處的前提是:需要同一個Session。如果使用打開兩次 Internet Explorer,甚至不同的 browser,就很容易看不到同一個 session 了。
範例程式下載