57

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

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

这些是 ASP.NET 应用程序不时“发生”的事情吗?有人会建议我们花大量时间尝试诊断导致问题的原因吗?

4

10 回答 10

51

这要看情况。由于多种原因,可能会发生无效的视图状态。

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

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

于 2009-02-23T09:36:17.400 回答
7

一个问题可能与用户路由器截断表单字段有关。解决这个问题的方法是在 web.config 中将 MaxPageStateFieldLength 设置为一个较小的数字(如 100),然后 ViewState 被分解为小块。做起来很简单,这篇文章对它进行了充分的解释。

于 2009-02-23T09:42:22.377 回答
4

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

但是,要缓解 ViewState 的问题,请考虑完全禁用它。作为 ASP.NET 开发人员,我们经常倾向于在各种不需要的地方使用 ViewState,因为它是默认设置。在考虑使用控件之前,我通常会考虑使用静态 html。如果您决定使用控件,请考虑是否真的需要启用 ViewState。禁用它通常会导致更好的页面加载时间,所以如果可以的话,就这样做。

我希望它在默认情况下被禁用,所以人们被迫以这种方式思考,但事实并非如此。

更新以回答评论:

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

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

  2. 如果您将数据绑定到真正静态的内容,您还可以考虑禁用 ViewState。有时我会找到一个列表,该列表数据绑定到数据库中的一个小型静态 basedata 表或类似的东西。现在,这可能很危险,但如果我确信数据不会更改,我可能会将数据作为静态内容移动到页面中(您可以将其包装在单独的控件中,这样您就不会拥有数据的多个静态副本)。但是,如果数据确实发生了变化,您将不得不手动更改它。

  3. 简单的控件(例如标签)通常是禁用 ViewState 的理想选择。

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

于 2009-02-23T09:53:08.937 回答
4

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

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

.NET 应用程序中不稳定的无效 Viewstate 问题

使用 ASP .Net Membership 使用户登录持久化

于 2009-08-19T14:19:03.717 回答
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

于 2017-07-03T14:00:04.960 回答
1

对于前者,您无能为力 - 我捕获此类异常并将用户退回到错误页面,并显示“您所在的页面已过期。这通常发生在您尝试重新访问您所在的页面时已经输入了数据。”

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

同样,除了在错误页面上显示适当友好的消息外,您无能为力。

于 2009-02-23T09:28:58.387 回答
1

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

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

我知道我真的应该大幅减小 ViewState 的大小,但这是一个大型遗留代码库,这样的更改将非常具有侵入性。

于 2013-12-04T18:18:09.197 回答
0

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

如果您的视图状态很大,那么最好使用 ASP.net 跟踪来查看哪些控件正在使用视图状态,以及您可以在哪里关闭它。

于 2009-08-06T20:47:52.123 回答
0

根据 Wayne Walter Berry 在这篇博文中的说法,另一个罪魁祸首可能是在 IE8 中使用 XHTML 文档类型,而页面上没有符合 XHTML 的标记。这会导致 IE8 向 scriptresource.axd 发送打乱的参数并抛出无效的视图状态异常。

他建议确保所有 javascript 块都使用// <![CDATA[]]>或简单地更改文档类型(这可能会导致页面上出现其他 css/样式问题)。

于 2009-08-29T16:07:39.453 回答
-2

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

于 2010-04-09T06:35:09.713 回答