﻿# 當 ASP.NET 發生 Viewstate MAC 的驗證失敗 ( machineKey )

問題是這樣的，當 ASP.NET 因為網頁還沒全部下載完成時，使用者就按下網頁中的任意一個 PostBack 的按鈕或連結時，就會發生 **Viewstate MAC 的驗證失敗** 的錯誤訊息！

這問題實在很難除錯(DEBUG)，我想很多人連發生的原因都不知道，主要的發生原因有兩種：

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

### 參考資料

-   [machineKey 項目 (ASP.NET 設定結構描述)](http://msdn2.microsoft.com/zh-tw/library/w8h3skw9\(VS.80\).aspx)
-   [ASP.NET machineKey Generator](https://www.codeproject.com/Articles/16645/ASP-NET-machineKey-Generator)
-   [ASP.NET machineKey Generator – DevelopmentNow](http://developmentnow.com/asp-net-machinekey-generator/)
-   Validation of viewstate MAC failed / The state information is invalid for this page and might be corrupted
-   [ASP.NET MachineKey自動產生原理剖析-黑暗執行緒](https://blog.darkthread.net/blog/inside-aspnet-autogenkeys/)
