項目順利完成,到客戶現場進行系統測試(使用VS2005進行壓力測試和響應測試),在系統日志中出 現如下錯誤:
[HttpException (0x80004005): Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that <machineKey> configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.]
應用程序部署在NLB環境,訪問MSCS集群的SQL Server 2005數據庫,包括應用程序服務器、數據庫服 務器、文件服務器等都可以做Failover。
在公司進行測試的時候,2.5倍於客戶現場測試的壓力下沒有此問題,所以主要懷疑受性能影響。
<1>服務器端檢查:客戶服務器優於開發測試用服務器為雙核酷睿(8 CPU),內存4GB,通過監 視程序沒有出現IIS進程超過2GB情況(基本在700MB左右)。
<2>客戶端檢查:因為是金融公司所以客戶端性能比測試用客戶端性能差很多,使用VS2005進行 測試的時候,每台機器只能分配500個用戶,CPU使用率達90%-100%。
懷疑由於客戶端能力比較差,頁面未能完全表示進行回發出現問題。通過查找資料,獲得如下信息:
* 確保你沒有使用Web Form
* 你使用了內置數據綁定控件(如GridView),並且由於綁定的數據中有主鍵或索引所以設置了 DataKeyNames屬性。
* 你的頁面表示的內容數據量大或加載時間比較長。
滿足以上條件時,如果頁面沒有完全加載到客戶端(IE)進行回發(Posting Back),你可能會看到 上面的異常信息。
此問題出現的原因是GridView等數據綁定控件使用DataKeyNames屬性時,請求ViewState加密。此方法 會在頁面</form>標簽的上方追加<input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="" />標簽。當請求的頁面信息量比較大,相應時間比較長的時候 ,客戶端可能還沒有完全表示就可以通過頁面的按鈕觸發服務器端回發(服務器端控件操作)。因為回發 的內容不包括加密標簽,回到服務器端進行驗證的時候就會失敗。(此問題不僅在測試軟件的情況下會出 現,經測試,在客戶使用系統的時候此問題也可能出現。)
解決此問題的方法是在web.config中關閉事件驗證和ViewState加密屬性的開關,如下:
<pages enableEventValidation="false" viewStateEncryptionMode ="Never" />
但請注意關閉開關引起的安全問題,稍後會發文討論Event Validation和ViewState Validation等安 全性設定內容的實質,討論使用場景。