問題是這樣的,當 ASP.NET 因為網頁還沒全部下載完成時,使用者就按下網頁中的任意一個 PostBack 的按鈕或連結時,就會發生 Viewstate MAC 的驗證失敗 的錯誤訊息!
這問題實在很難除錯(DEBUG),我想很多人連發生的原因都不知道,主要的發生原因有兩種:
-
當網站採用 Web-farm 架構時,也就是一個網站採用負載平衡的架構,用多台 Web 主機同時提供服務時。
因為 ASP.NET 預設會將 Viewstate 編碼加密,驗證資料的加密類型是 SHA1,驗證加密資料的金鑰(Key)預設是「自動產生」,所以每一台Web主機所產生的Key都不一樣,所以你採用多台主機同時提供服務時,就可能會遇到從第一台Web主機讀到的內容,做 PostBack 時可能會 PostBack 到第二台主機,但第二台主機看不懂第一台主機編碼過的 Viewstate,而導致「Viewstate MAC 的驗證失敗」的例外發生!
這時你需要統一每一台主機的 machineKey 才能讓每一台的編碼加密的內容可以被正確驗證!建議您去 The Code Project 網站看這份 ASP.NET machineKey Generator 文件,上面有完整說明!
也可以到我寫的 ASP.NET 2.0+ MachineKey Generator 機器金鑰生器產生出結果,然後放到 web.config
的 <system.web>
區段下即可,如下範例:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
...
<system.web>
...
<machineKey
validationKey="7626F91C8AEEEA2F126270ABB4B0DE36C2EF9BFD8D55D3F66D552276687FB85909C155EE6A26A3D617C588E6C42EEB8301098E98DAD6F29A20A6127EB6175F79"
decryptionKey="245626CEA85BC34230D45467E607DBEF3862305E088EA2E5F8B8DA81F338B465"
validation="SHA1" decryption="AES"
/>
...
</system.web>
...
</configuration>
-
因為網頁還沒全部下載完成,導致頁面的狀態不完整時就對伺服器發出 PostBack 要求,因為 ViewState 不完整,而導致 Viewstate 驗證失敗。
這個問題只能將修改網站的 web.config
設定將 Viewstate 全部關閉才不會發生錯誤!如下:
<pages enableEventValidation="false" viewStateEncryptionMode ="Never" />
參考資料