我应该忽略偶尔出现的无效视图状态错误吗?

时间:2009-02-23 09:21:34

标签: asp.net error-handling viewstate

每隔一段时间(每天一次)我们在ASP.NET 3.5应用程序的日志中看到以下类型的错误

  • 无效的视图状态
  • 无效的回发或回调参数

这些东西是否只是偶然发生在ASP.NET应用程序中?有人会建议我们花很多时间来诊断造成问题的原因吗?

10 个答案:

答案 0 :(得分:49)

这取决于。无效的视图状态可能由于各种原因而发生。

  1. 在用户在页面上进行回发之前,Viewstate太大并且尚未完成呈现。修复通常是禁用所有触发回发的控件,并在页面加载完成后启用客户端 - 请参阅http://blogs.msdn.com/tom/archive/2008/03/14/validation-of-viewstate-mac-failed-error.aspx
  2. 您正在使用视图状态MAC(出于安全原因,您应该这样做)但是您没有设置机器密钥并且应用程序池已经循环生成了新的密钥。不要忘记设置ViewStateUserKey。
  3. 有人在Mac上使用旧版本的IE,它会截断隐藏的表单字段。在这种情况下,您需要将视图状态移出页面session state
  4. Viewstate MAC问题通常表明您在Web场中并且忘记在web.config中设置计算机密钥。但是,如果你这样做了,那么可能有人试图做坏事(机器人发布评论,有人试图触发禁用控件的事件等)。如果只是为了排除潜在的安全问题,应该追踪这些问题的原因。 / LI>

    无论您做什么 关闭视图状态或事件验证。

答案 1 :(得分:7)

一个问题可能与用户路由器截断表单字段有关。解决这个问题的方法是在web.config中将MaxPageStateFieldLength设置为较小的数字(如100),并将ViewState分解为小块。这很简单,this article完全解释了它。

答案 2 :(得分:4)

例外不会“偶然发生”。它们总是出于正当理由而出现,其中一些已在其他答案中列出。

但是,为了缓解ViewState的问题,请考虑完全禁用它。作为ASP.NET开发人员,我们经常倾向于在不需要它的所有类型的地方使用ViewState,因为它是默认的。在考虑使用控件之前,我通常会考虑使用静态html。如果您决定使用控件,请考虑是否确实需要启用ViewState。禁用它通常会导致更好的页面加载时间,所以如果可以,请执行此操作。

我希望它默认是禁用的,所以人们不得不这么想,但事实并非如此。

更新回复评论:

在我的头脑中,我想出了3个关闭ViewState的机会。

  1. 如果每次回发都加载了数据,则禁用ViewState。如果您正在构建支持AJAX的站点(真正的 AJAX而不是UpdatePanel类型;)),通常会出现这种情况,您通常在第一次加载时加载数据,然后使用AJAX重新加载/更新数据要求。在某些情况下,您甚至可能在每次访问时加载数据,仅用于禁用ViewState,然后在服务器上缓存数据。

  2. 如果您将数据绑定到非常静态的内容,也可以考虑禁用ViewState。有时我会找到一个数据库,它被数据绑定到数据库中的一个小的静态基础数据表或类似的东西。现在,这可能是危险的,但如果我确信数据不会改变,我可能会将数据作为静态内容移动到页面中(您可以将其包装在单独的控件中,这样您就不会有多个数据的静态副本)。但是,如果数据随后发生变化,则必须手动更改。

  3. 标签之类的简单控件通常是禁用ViewState的理想选择。

  4. 最后你可以切换到ASP.NET MVC框架并永远挥手告别这些问题,这就是我打算做的事情,即使我将面临其他一些问题。 ;)

答案 3 :(得分:4)

BlowDart对于无效的Viewstate问题有正确的答案。这可能是您的应用程序池被回收并更改加密密钥。

请参阅这些帖子以获取支持:

Erratic Invalid Viewstate issue in a .NET application

Making user login persistant with ASP .Net Membership

答案 4 :(得分:2)

无效的观看状态对您的记录器或用户或您的网站没有任何价值,最终用户永远不会看到这些错误。 要避免此错误,请尝试在 Global.ascx

中添加以下内容
void Application_Error(object sender, EventArgs e)
    {          
                if (ex is HttpException && ex.InnerException is ViewStateException)
                {
                    Response.Redirect(Request.Url.AbsoluteUri);
                    return;
                }
    }

了解更多信息,请查看以下链接:

https://www.karpach.com/viewstateexception-invalid-viewstate.htm

答案 5 :(得分:1)

关于前者你无能为力 - 我捕获了这些异常并将用户弹回错误页面,其中包含“您所在的页面已过期”的消息。这通常发生在您尝试重新访问时您已输入数据的页面。“

我在使用UpdatePanels的相当大的页面上看到后者最多。我认为这是用户在页面加载完之前回发(或可能回调)的时候,所以并非所有在页面末尾标记的javascript都已运行。

同样,除了在错误页面上显示适当友好的消息之外,您无法做多少事情。

答案 6 :(得分:1)

我在日志中抛出了这种异常,并且与此处列出的其他内容有着截然不同的原因。我确实有一个非常大的ViewState,这是问题的一部分。但这与另一个问题相结合导致了这些异常(可能偶尔会有来自IIS的不良反应)。

我正在处理的代码库有一些奇特的代码以避免双击,并且作为其中的一部分,它向每个按钮的单击事件的javascript添加一些内容,在第一次单击后禁用按钮,然后执行通常的回发。但是这样调用回发是一个问题,因为我的一些按钮已经自动生成了由.NET生成的回发调用。所以我最终得到了双重回发,其中一个回复有一个无效的ViewState。删除额外的回发阻止了我的例外。

我知道我应该大幅度减少ViewState的大小,但这是一个庞大的遗留代码库,而且这样的更改会非常具有侵略性。

答案 7 :(得分:0)

忽略此错误可能不是一个好主意。除了上述所有答案之外,您可能还需要考虑查看视图状态的大小。代理服务器可以截断大型视图状态。

如果您的视图状态很大,那么最好使用ASP.net跟踪来查看使用viewstate的控件,以及可以将其关闭的位置。

答案 8 :(得分:0)

根据Wayne Walter Berry在this博客文章中的另一个罪魁祸首可以在IE8中使用XHTML文档类型而不在页面上使用符合XHTML的标记。这可能导致IE8将乱序参数发送到scriptresource.axd并抛出无效的viewstate异常。

他建议确保所有javascript块都包含// <![CDATA[]]>或只是更改doctype(这可能会导致页面上出现其他css /样式问题)。

答案 9 :(得分:-2)

更新:微软宣布IE 8的以下错误修复解决了这个问题:
http://blogs.msdn.com/ieinternals/archive/2010/04/01/IE8-Lookahead-Downloader-Fixed.aspx