﻿# 如何設定與啟用 ASP.NET 的 SQLServer 工作階段狀態模式

今天有同事請我幫忙設定讓 ASP.NET 網站能改用 SQL Server 當作 **工作階段狀態** (Session State) 的提供者，剛好乘機將設定的過程筆記一下，其實設定過方法並不複雜，只要下幾個指令並修改 web.config 即可完成，總共也只有幾個步驟而已，其中的注意事項我也會提到一些。

要使用 SQL Server 當作 **工作階段狀態** (Session State) 的提供者，主要只有兩個步驟：

1.  建立 **工作階段狀態** (Session State) 所需的資料庫
2.  修改 ASP.NET 網站的 web.config

一、建立 **工作階段狀態** (Session State) 所需的資料庫

建立 Session State 專用的資料庫在安裝完 Microsoft .NET Framework 執行環境後就會有一支程式可以幫你自動建立所需的資料庫（注意：不需要安裝 SDK 就有這個工具），此工具程式的路徑如下：

```
C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe
```

在命令提示字元輸入 **C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727\\aspnet\_regsql.exe -?** 即可取得完整的使用說明，其中就有關於「工作階段狀態選項」的說明，如下圖示：

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/5d6b2474981859e4f2ab-image_thumb_70.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/ee5812cc0c72b3c9bc2d-image_1087.png)

除了「SQL 連接選項」非常重要外，在「工作階段狀態選項」裡也有幾個重要的選項以及注意事項，那就是 **–sstype** 這個選項，他區分了三種支援的類型，看上圖的中文說明應該能獲得理解，但我還是特別提醒一下，由於 ASP.NET 裡面的 Session State 經常會儲存一些重要的資訊，例如購物車資訊、會員的登入狀態等等，如果你今天沒有輸入 **–sstype** 選項的話，預設會是 **t: 暫存**，也代表著若 SQL Server 重新啟動或 Fail-over 之後，所有的 Session 資料將會消失不見。（因為 SQL Server 只要重新啟動就會重建 tempdb 系統資料庫，所以所有 Session 資料都將會被清空）

所以一般對於 Session 資料完整性比較嚴謹的網站，通常會選擇 **p: 永續性** 的方式來建立資料庫，這樣一來就算 SQL Server 重新啟動也不會導致 Session 資料流失的問題。

以下是幾個常見的指令執行範例：

**\[ 安裝工作階段狀態資料庫 \]**

**請先進入 C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727 目錄再執行以下指令：**

**\* 使用 Windows 驗證連線 ( 信任式連線 )**

```
aspnet_regsql.exe –S . -E -ssadd -sstype p
```

**\* 使用 SQL Server 驗證連線 ( 請將 sa 換成 SQL Server 登入帳號、將 pw 換成 SQL 登入密碼 )**

```
aspnet_regsql.exe -S . -U sa -P pw -ssadd -sstype p
```

**\* 使用自訂的資料庫名稱**

```
aspnet_regsql.exe -S . -E -ssadd -sstype c –d MySessionDB
```

**\[ 移除工作階段狀態資料庫 \]**

**請先進入 C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727 目錄再執行以下指令：**

**\* 使用 Windows 驗證連線 ( 信任式連線 )**

```
aspnet_regsql.exe –S . -E -ssremove -sstype p
```

**\* 使用 SQL Server 驗證連線 ( 請將 sa 換成 SQL Server 登入帳號、將 pw 換成 SQL 登入密碼 )**

```
aspnet_regsql.exe -S . -U sa -P pw -ssremove -sstype p
```

在安裝完成之後，你會發現 SQL Server 會有一些物件與作業被建立，如下解說：

1\. 預設資料庫名稱為 ASPState

2\. 建立兩個資料表 ASPStateTempApplications 與 ASPStateTempSessions

3\. 建立多個所需的預存程序

    ![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/c76be39bffc7935f471c-image_1088.png)

4\. 並且會在 SQL Server Agent 裡建立一個 ASPState\_Job\_DeleteExpiredSessions 作業，用來定時清理過期的 Session 資料，而且預設每分鐘就會自動執行一次：

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/52d1ea7d1e13bb6a401d-image_1091.png)

[![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/88425b2d1c6a6d6e4433-image_thumb_71.png)](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/efd38cf6f7845f47580d-image_1090.png)

如果你想要得到建立這個資料庫的完整 DDL 指令碼，可以使用以下指令匯出指令碼，如此以來你可以更進一步的分析 aspnet\_regsql.exe 到底對資料庫下了哪些 T-SQL 指令：

```
aspnet_regsql.exe -E -S . -ssadd -sstype p -sqlexportonly c:\Create_ASPState.sql
```

執行完以上指令後，即可獲得 c:\\Create\_ASPState.sql 指令檔。

**§ 請注意**：由於 SQLEXPRESS 不支援 SQL Server Agent，這會導致 Session 資料不會自動被清除，資料庫只要跑得越久 Session 資料就會越多，直到資料庫大小到達限制的容量時 ASP.NET 就會發生無法寫入 Session 的錯誤，因此需自行透過 **[sqlcmd](http://msdn.microsoft.com/zh-tw/library/ms180944.aspx)** 指令在 **ASPState** 資料庫執行以下**預存程序**並設定到工作排程中定時執行才可以：

```
EXECUTE DeleteExpiredSessions
```

二、修改 ASP.NET 網站的 web.config

其 web.config 中使用 SQLServer 工作階段狀態模式的語法如下：

**\[使用預設的 ASPState 資料庫名稱\]**

```xml
<sessionstate mode="SQLServer" timeout="60"
 sqlconnectionstring="Data Source=Server;Integrated-Security=SSPI;"
 cookieless="false">
```

**\[使用自訂的資料庫名稱\]**

```xml
<sessionState mode="SQLServer" allowCustomSqlDatabase="true"
 sqlConnectionString="Server=.;Database=ASPState;Integrated Security=true" 
 sqlCommandTimeout="60" 
 cookieless="false" cookieName="ASP.NET_SessionId" timeout="60" />
```

**相關連結**

-   [ASP.NET SQL Server 註冊工具 (aspnet\_regsql.exe)](http://msdn.microsoft.com/zh-tw/library/ms229862.aspx)
-   [工作階段狀態模式](http://msdn.microsoft.com/zh-tw/library/ms178586\(v=VS.100\).aspx)
-   [sessionState 項目 (ASP.NET 設定結構描述)](http://msdn.microsoft.com/zh-tw/library/h6bb9cz9\(v=vs.80\).aspx)
-   [Configuring ASP session state on SQL server](http://www.codeproject.com/Articles/104082/Configuring-ASP-session-state-on-SQL-server)
-   [如何讓 ASP.NET 使用 Session 資料時不要再自動消失](/post/2008/01/12/How-to-avoid-Session-data-loss-in-ASPNET.aspx)
-   [如何讓【ASP.NET 狀態服務】開放遠端連接](/post/2008/01/12/How-to-let-ASPNET-State-Service-allow-remote-connection)
-   [Using ASPNET\_RegSQL.exe with SQL Express databases in APP\_DATA](https://weblogs.asp.net/lhunt/425966)
