我应该忽略偶尔的无效viewstate错误?
每隔一段时间(每天一次),我们在ASP.NET 3.5应用程序的日志中看到以下types的错误
- 无效的视图状态
- 回发或callback参数无效
这些事情是否会随时随地通过ASP.NET应用程序发生? 有人会build议我们花费大量的时间来尝试诊断是什么原因造成的问题?
这得看情况。 无效的视图状态可能由于各种原因而发生。
- Viewstate太大,在用户在页面上回发之前还没有完成渲染。 解决方法通常是禁用触发回发的所有控件,并在页面加载完成后启用客户端 – 请参阅http://blogs.msdn.com/tom/archive/2008/03/14/validation-of-viewstate- MAC-失败,error.aspx
- 您正在使用viewstate MAC(出于安全原因,您应该是),但是您没有设置机器密钥,并且应用程序池已经回收并生成新的MAC。 不要忘记设置一个ViewStateUserKey。
- 有人在Mac上使用旧版本的IE来截断隐藏的表单字段。 在这种情况下,您需要将viewstate移出页面进入会话状态 。
- Viewstate MAC问题通常表明您在Web场中,并忘记在web.config中设置机器密钥。 但是,如果你这样做,那么可能是有人试图做坏事(机器人张贴评论,有人试图触发禁用控制的事件等)。只要排除潜在的安全问题,应该跟踪这些原因。
不pipe你做什么,都不要closures视图状态或事件validation。
一个问题可能是用户路由器截断表单域。 解决这个问题的方法是在web.config中将MaxPageStateFieldLength设置为一个小数字(比如100),并将ViewState分解成小块。 这是非常简单的, 这篇文章充分解释。
BlowDart有无效Viewstate问题的正确答案。 这可能是您的应用程序池正在回收和更改encryption密钥。
看到这些post的支持:
在.NET应用程序中的不稳定无效的Viewstate问题
通过ASP .Net成员身份使用户login持久
例外情况不会“不时发生”。 他们总是出于正当的理由,其中一些已经在其他答案中列出。
但是,为了缓解ViewState的问题,可以考虑彻底禁用它。 作为ASP.NET开发人员,我们经常倾向于在各种不需要的地方使用ViewState,因为它是默认的。 在考虑使用控件之前,我通常会考虑使用静态html。 如果您决定使用控件,请考虑是否确实需要启用ViewState。 禁用它通常会导致更好的页面加载时间,所以如果可以的话,就这样做。
我希望它被默认禁用,所以人们被迫这样想,但事实并非如此。
更新回答评论:
在我的头顶,我想出了3个closuresViewState的机会。
-
如果数据在每个回发中加载,则禁用ViewState。 如果你正在构buildAJAX的网站(这是真正的 AJAX而不是UpdatePanel的types),这通常会是这种情况,你通常在第一次加载时加载数据,然后使用AJAX请求重新加载/更新数据。 在某些情况下,您甚至可能在每次访问时加载数据,仅用于禁用ViewState,然后将数据caching到服务器上。
-
如果将数据绑定到非常静态的内容,也可以考虑禁用ViewState。 有时我会发现一个数据绑定到数据库中的一个小型静态基础表的列表或类似的东西。 现在,这可能是危险的,但如果我确信数据不会改变,我可能会将数据作为静态内容移动到页面中(您可以将其包装在单独的控件中,这样就不会有数据的几个静态副本)。 但是,如果数据然后改变,你将不得不手动改变它。
-
简单的控件(如标签)通常是禁用ViewState的理想select。
最后,你可以切换到ASP.NET MVC框架,并永远挥手告别这些问题,这就是我打算做的,即使我会面临一些其他问题。 ;)
对于前者,你可以做的事情不多 – 我会捕获这样的exception,并将用户跳转到一个错误页面,并沿着“你所在的页面已经过期的信息”,这通常发生在你试图重新访问一个页面已经input数据了。“
我看到后者使用UpdatePanels的相当大的页面上。 我认为这是用户回发(或可能callback)之前,页面已完成加载,所以不是所有的标签在页面末尾的JavaScript已经运行。
同样,除了在错误页面上显示一个适当友好的信息之外,你可以做的事情也不多。
忽略这个错误可能不是一个好主意。 除了上面的所有答案之外,您还可以考虑查看您的视图状态有多大。 一个大的视图状态可以被代理服务器截断。
如果您的视图状态很大,那么使用ASP.net跟踪来查看哪些控件正在使用viewstate,以及可以closures它的位置可能是一个好主意。
根据韦恩·沃尔特·贝瑞(Wayne Walter Berry)在这篇博客文章中指出,另一个罪魁祸首可能是在IE8中使用XHTML文档,而页面上没有符合XHTML的标记。 这可能导致IE8发送scrambled参数给scriptresource.axd并抛出无效的viewstateexception。
他build议确保所有的JavaScript块都包含有// <![CDATA[]]>
或者只是改变文档types(这可能会导致页面上的其他CSS /样式问题)。
我把这种例外情况扔在我的日志里,和这里列出的其他人有很大的不同。 我确实有一个非常大的ViewState,这是问题的一部分。 但是,这与另一个问题相结合,导致这些exception(并可能偶尔从IIS的不良反应)。
我正在处理的代码库有一些奇特的代码,以避免双击,作为它的一部分,它添加了一些东西到每个button的点击事件的JavaScript,在第一次点击后禁用button,然后做通常的回发。 但是像这样调用回发是一个问题,因为我的一些button已经有一个由.NET自动生成的回发调用。 所以我结束了双回发,其中之一有一个无效的ViewState。 删除多余的回发为我停止了例外。
我知道我应该真的大大减lessViewState的大小,但这是一个很大的遗留代码基础,这样的变化将是非常有创意的。
无效的视图状态对您的logging器,用户或您的网站没有任何价值,最终用户永远不会看到这些错误。 为避免此错误,请尝试在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
更新:微软宣布IE 8的下列错误修正解决了这个问题:
http://blogs.msdn.com/ieinternals/archive/2010/04/01/IE8-Lookahead-Downloader-Fixed.aspx