在进一步阅读之前,请排除以下先决条件:
- 您没有使用网络场。
- 当使用使用“DataKeyNames”的内置数据绑定控件(例如 GridView、DetailsView 或 FormView)时,它会出现。
- 如果您有一个因任何原因加载缓慢的大页面,就会出现这种情况。
如果以下前提条件为真并且您单击回发控件/链接并且页面尚未在客户端浏览器中完全加载,您可能会收到“验证 ViewState MAC 失败”异常。
发生这种情况时,如果您只是尝试将页面属性“EnableViewStateMac”设置为 false,它并不能解决问题,它只会更改相同导航行为中的错误消息:
此页面的状态信息无效,可能已损坏。
出现此异常是因为使用 DataKeyNames 的控件需要对 Viewstate 进行加密。当 Viewstate 被加密时(默认模式 Auto,如果控件需要,则加密,否则不加密),Page 在关闭 <form> 标记之前添加字段。但是这个隐藏字段可能没有被呈现给浏览器长时间运行的页面,如果你在它之前进行回发,浏览器会在没有这个字段的情况下启动回发(在表单发布集合中)。最终结果是,如果在回发时省略该字段,则页面不知道 Viewstate 已加密并导致上述异常。IE 页面预计在您进行回发之前已完全加载。
顺便说一下,事件验证也有类似的问题,因为 __EVENTVALIDATION 字段也呈现在表单的末尾。这是一项安全功能,可确保回发操作仅来自服务器允许和创建的事件,以帮助防止欺骗性回发。此功能是通过让控件在渲染时注册有效事件来实现的(如在其实际的 Render() 方法期间)。最终结果是,在您呈现的 <form> 标记的底部,您会看到如下内容: 。当回发发生时,ASP.NET 使用存储在此隐藏字段中的值来确保您单击的按钮调用有效事件。如果它无效,则会出现上述异常。
当您在呈现 EventValidation 字段之前回发时,就会出现此问题。如果启用了 EventValidation(默认情况下启用),但 ASP.net 在您回发时看不到隐藏字段,您也会遇到异常。如果您在表单完全呈现之前提交表单,则可能 EventValidation 字段尚未呈现,因此 ASP.NET 无法验证您的点击。
解决方法
将enableEventValidation 设置为 false 并将 viewStateEncryptionMode 设置为 Neve r,如下所示:
<pages enableeventvalidation="false" viewstateencryptionmode="Never">
这具有禁用验证和加密的不良副作用。在某些网站上,这样做可能没问题,但这不是最佳做法,尤其是在面向公众的网站中。
有关详细信息和其他解决方法,请参阅此博客条目。