今天在調試Atlas時遇到錯誤:
驗證視圖MAC失敗。如果此引用程序由網絡場或羣集承載,請確保<machineKey>配置指定了相同的 validationKey 和驗證算法。不能在羣集中使用 AutoGenerate
發生錯誤的環境:
ASP.NET 2.0,使用Atlas的UpdatePanel,在UpdatePanel中動態加載用戶控件,以達到動態更新頁面的效果。其中有一個用戶控件中使用了GridView。當動態切換頁面時,出現上述錯誤。
問題分析:
經過一番搜索,找到以下的文章:
http://aspadvice.com/blogs/joteke/archive/2006/02/02/15011.aspx
http://forums.asp.net/1173230/ShowPost.aspx
分析後找到了問題的根源。首先,文章中提到,如果用GridView,並且指定了DataKeyNames屬性,則出於安全的理由(因爲DataKeyNames指定的字段代表數據的主鍵,且該主鍵值需要保存在視圖狀態中發送到客戶端,用戶如果篡改主鍵值,會導致安全問題),GridView會要求加密視圖狀態。爲此會自動在頁面表單</forms>之前添加一個<input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="" /> 。
然而,Atlas的UpdatePanel要求放置在<form></form>內部,也就是</form>之前。這就意味着添加的隱藏input控件沒有被放置在UpdatePanel內,而是放置在UpdatePanel和</form>之間。
當UpdatePanel更新時,UpdatePanel內部的控件被提交到服務器進行處理(Patrial Rendering),而整個頁面並沒有被提交。也就是說隱藏的input控件沒有隨着一起提交。因此服務器並不知道提交的ViewState被加密了,從而導致MAC驗證錯誤。
解決方法:
通過在Web.config裏邊添加
<pages enableEventValidation="false" viewStateEncryptionMode ="Never" />
可以解決該問題。
如果這個解決不了
<pages enableEventValidation="false" viewStateEncryptionMode="Never" enableViewStateMac="false"/>