时不时地(每天一次左右)我们在 ASP.NET 3.5 应用程序的日志中看到以下类型的错误
- 无效的视图状态
- 无效的回发或回调参数
这些是 ASP.NET 应用程序不时“发生”的事情吗?有人会建议我们花大量时间尝试诊断导致问题的原因吗?
时不时地(每天一次左右)我们在 ASP.NET 3.5 应用程序的日志中看到以下类型的错误
这些是 ASP.NET 应用程序不时“发生”的事情吗?有人会建议我们花大量时间尝试诊断导致问题的原因吗?
这要看情况。由于多种原因,可能会发生无效的视图状态。
无论您做什么,都不要关闭视图状态或事件验证。
一个问题可能与用户路由器截断表单字段有关。解决这个问题的方法是在 web.config 中将 MaxPageStateFieldLength 设置为一个较小的数字(如 100),然后 ViewState 被分解为小块。做起来很简单,这篇文章对它进行了充分的解释。
例外不会时不时地“发生”。它们总是出于正当理由而发生,其中一些已经在其他答案中列出。
但是,要缓解 ViewState 的问题,请考虑完全禁用它。作为 ASP.NET 开发人员,我们经常倾向于在各种不需要的地方使用 ViewState,因为它是默认设置。在考虑使用控件之前,我通常会考虑使用静态 html。如果您决定使用控件,请考虑是否真的需要启用 ViewState。禁用它通常会导致更好的页面加载时间,所以如果可以的话,就这样做。
我希望它在默认情况下被禁用,所以人们被迫以这种方式思考,但事实并非如此。
更新以回答评论:
在我的脑海中,我想出了 3 个关闭 ViewState 的机会。
如果在每次回发时都加载数据,则禁用 ViewState。如果您正在构建启用 AJAX 的网站(那是真正的AJAX 而不是那种 UpdatePanel ;)),通常会出现这种情况,您通常在第一次加载时加载数据,然后使用 AJAX 请求重新加载/更新数据。在某些情况下,您甚至可能仅出于禁用 ViewState 的目的在每次访问时加载数据,然后将数据缓存在服务器上。
如果您将数据绑定到真正静态的内容,您还可以考虑禁用 ViewState。有时我会找到一个列表,该列表数据绑定到数据库中的一个小型静态 basedata 表或类似的东西。现在,这可能很危险,但如果我确信数据不会更改,我可能会将数据作为静态内容移动到页面中(您可以将其包装在单独的控件中,这样您就不会拥有数据的多个静态副本)。但是,如果数据确实发生了变化,您将不得不手动更改它。
简单的控件(例如标签)通常是禁用 ViewState 的理想选择。
最后,您可以切换到 ASP.NET MVC 框架并永远告别这些问题,这就是我打算做的事情,即使我将面临一些其他问题。;)
BlowDart 对 Invalid Viewstate 问题有正确的答案。可能是您的应用程序池被回收并更改了加密密钥。
请参阅这些帖子以获得支持:
无效的视图状态对您的记录器或用户或您的网站没有任何价值,最终用户永远不会看到这些错误。为避免此错误,请尝试在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
对于前者,您无能为力 - 我捕获此类异常并将用户退回到错误页面,并显示“您所在的页面已过期。这通常发生在您尝试重新访问您所在的页面时已经输入了数据。”
我在使用 UpdatePanel 的相当大的页面上看到的最多的是后者。我认为这是在页面完成加载之前用户发回(或可能回调)的时候,因此并非所有在页面末尾标记的javascript都已运行。
同样,除了在错误页面上显示适当友好的消息外,您无能为力。
我的日志中抛出了这种异常,并且与此处列出的其他原因有很大不同。我确实有一个非常大的 ViewState,这是问题的一部分。但这与导致这些异常的另一个问题相结合(并且可能偶尔来自 IIS 的错误响应)。
我正在处理的代码库有一些花哨的代码来避免双击,作为其中的一部分,它向每个按钮的单击事件的 javascript 添加了一些东西,在第一次单击后禁用按钮,然后执行通常的回发。但是像这样调用回发是一个问题,因为我的一些按钮已经有一个由 .NET 自动生成的回发调用。所以我最终得到了双重回发,其中一个有无效的 ViewState。删除额外的回发为我停止了例外。
我知道我真的应该大幅减小 ViewState 的大小,但这是一个大型遗留代码库,这样的更改将非常具有侵入性。
忽略此错误可能不是一个好主意。除了上述所有答案之外,您可能还需要考虑查看您的视图状态有多大。代理服务器可以截断大的视图状态。
如果您的视图状态很大,那么最好使用 ASP.net 跟踪来查看哪些控件正在使用视图状态,以及您可以在哪里关闭它。
根据 Wayne Walter Berry 在这篇博文中的说法,另一个罪魁祸首可能是在 IE8 中使用 XHTML 文档类型,而页面上没有符合 XHTML 的标记。这会导致 IE8 向 scriptresource.axd 发送打乱的参数并抛出无效的视图状态异常。
他建议确保所有 javascript 块都使用// <![CDATA[]]>
或简单地更改文档类型(这可能会导致页面上出现其他 css/样式问题)。
更新:微软宣布以下针对 IE 8 的错误修复修复了此问题:http:
//blogs.msdn.com/ieinternals/archive/2010/04/01/IE8-Lookahead-Downloader-Fixed.aspx