来自asp.net应用程序的奇怪的未处理异常-验证视图状态MAC失败
我不知道以前是否有人见过这个问题,但是我很困惑。这是我的错误页面正在捕获的未处理的异常消息。
Error Message: Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster. Stack Trace: at System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) at System.Web.UI.HiddenFieldPageStatePersister.Load() at System.Web.UI.Page.LoadPageStateFromPersistenceMedium() at System.Web.UI.Page.LoadAllState() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) at System.Web.UI.Page.ProcessRequest() at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) at System.Web.UI.Page.ProcessRequest(HttpContext context) at ASP.generic_aspx.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) Source: System.Web
有人对我该如何解决这个问题有任何想法吗?谢谢。
解决方案
我似乎记得,如果在页面完全加载之前单击按钮/链接等,就会发生此错误。
在这种情况下,该错误是由称为事件验证的ASP.net 2.0功能引起的。这是一项安全功能,可确保回发操作仅来自服务器允许和创建的事件,以帮助防止欺骗性的回发。通过使控件在呈现时注册有效事件(例如,在其实际的Render()方法期间)来实现此功能。最终结果是在渲染的底部
表单标签,我们将看到类似以下内容的内容:
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="AEBnx7v.........tS" />
发生回发时,ASP.net使用存储在此隐藏字段中的值来确保我们单击的按钮调用有效事件。如果无效,则会得到我们一直看到的异常。
我们看到的问题特别是在呈现EventValidation字段之前回发时发生。如果启用了EventValidation(默认情况下为EventValidation),但在回发时ASP.net看不到隐藏字段,我们也会收到异常。如果在表单完全呈现之前提交表单,则很有可能尚未呈现EventValidation字段,因此ASP.net无法验证单击。
当然,一种解决方法是仅禁用事件验证,但是我们必须意识到安全隐患。或者,永远不要在表单完成渲染之前回发。当然,这很难告诉用户,但是也许我们可以禁用UI,直到呈现表单为止?
来自http://forums.asp.net/p/955145/1173230.aspx
我们是否有多个运行该应用程序的服务器和/或者一个网络花园?如果是,则必须在web.config中设置机器密钥
我知道我们可以禁用viewstate MAC的验证,但是我认为,如果未加载该页面,我们会遇到更多麻烦。当我遇到这个问题时,我不得不禁用所有按钮,直到页面完全加载为止。
@克里斯
如果问题是在页面完全呈现之前单击某个项目,则asp.net 3.5 SP1在页面元素上添加了一个名为renderAllHiddenFieldsAtTopOfForm的web.config条目。
默认情况下,ASP.NET在页面中包含ViewState值的数字签名。它是通过自动生成的密钥保存在内存中来实现的。这样做是为了防止恶意用户从浏览器更改ViewState,例如,授予他(她)自己通常无法访问的内容的访问权限。
ASP.NET也可以选择对ViewState进行加密,但是出于性能原因,默认情况下将其关闭。在许多网站中,确保不对ViewState的内容进行"伪造"比对它保密是非常重要的。
该错误消息表明签名验证失败。该页面发布有ViewState,但是ViewState签名与服务器持有的密钥计算出的签名不匹配。
发生此错误的最常见原因是,我们在类似服务器场的环境中使用了两个或者多个Web服务器:一台服务器发送原始页面,并用该服务器上的内存中的密钥签名,但是该页面被发回到第二个(或者第三个...)服务器。由于两个或者多个服务器不共享签名密钥,因此签名不匹配。
...If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.
错误消息告诉我们,是在web.config中使用validationKey属性(请参见MSDN中的详细信息)将签名密钥硬编码为所有服务器共享的值,而不是使用动态生成的值。这样,签名验证就可以成功完成,而与哪个服务器接收回发无关。
我们可以关闭验证,但是这样做非常危险。这意味着任何有一点空闲时间的黑客都可以在应用程序中伪造值。例如,如果我们将商品的价格保持在ViewState值中,那么黑客可能会在下订单之前将其值从浏览器更改为$ 0.01.
对于其他最终在此问题上苦苦挣扎的人,这里是一些解决方法的有用链接:
http://blogs.msdn.com/tom/archive/2008/03/14/validation-of-viewstate-mac-failed-error.aspx