无法在 NLB 上加载视图状态
Posted
技术标签:
【中文标题】无法在 NLB 上加载视图状态【英文标题】:Failed to load viewstate on NLB 【发布时间】:2011-07-04 13:35:18 【问题描述】:我们有一个系统,可以在每次回帖时动态创建页面控件,并使用浏览器历史记录等进行处理。
问题在于,在生产服务器(NLB 上的 2 个节点)上,我们在没有发现相关性的不同位置随机出现,加载视图状态失败,控制树可能是不同的错误。但是,在我们的登台服务器上完全相同的代码(与生产相同的 NLB 设置)从未发生过。
此时我基本上排除了它的代码,因为它根本不会发生在开发/暂存或本地环境中,而在生产环境中它相当频繁。这让我相信我们在某个地方存在配置错误。
我在用于登台和生产的 web.config 中设置了硬编码的机器密钥,并且会话支持 MSSQL。
如果有人有建议让我朝着正确的方向前进,那就太好了,我们整个开发团队都会为此感到难过。
我们的 webconfig 位于 pastbin:http://pastebin.com/m2kRTd0k
【问题讨论】:
几年前我在 SO 上发布了一个类似的问题,它可能是相关的。见这里:***.com/questions/343153/… 请求很短,视图状态并不接近您问题答案中指示的长度。这是来自提琴手的帖子请求:pastebin.com/J2HaL51D 唯一奇怪的是 __viewstateencrypted=&... 但不知道它是否应该是这样。 那么,生产区和暂存区有什么不同呢?同意程度?客户多元化?一些微妙或被忽视的配置设置?也许是一些物理变化、硬件或环境...... 到目前为止,我发现的唯一一件事是我们的 iis 在生产中绑定到 ip 而不是主机名,并且 Windows 更新被禁用。我现在正在运行 Windows 更新,所以它与我们的暂存环境版本相同。 网站也运行 SSL。仍然没有解决它,我降低了它发生的频率,由于某种原因,它试图将它们反弹到 404 的表单登录页面,在我们的暂存框上设置相同的方式,但它从未将它们重定向到那里。我将其重定向到正确的位置,它减慢了此错误的频率。仍然发生了一点。 【参考方案1】:您可以检查以下几点:
您确定您编辑的 web.config 文件是使用的吗?尝试在其中添加语法错误,然后查看是否出现错误。 检查您的舞台环境中是否未配置 Sticky IP 检查您的环境是否处于相同的补丁级别,可能其中一个的默认值与另一个不同。 这两个环境所在的网络基础架构也可能有所不同【讨论】:
web.config 肯定被使用了。没有粘性 ip 设置,修补到相同级别的 Windows 更新。考虑到我们的生产环境在 colo 并且舞台在内部,该网络实际上尽可能接近。两台服务器是具有相同 Windows 图像的相同 vCenter 框。【参考方案2】:我的公司有一个完全由数据库驱动的动态调查表。
由于问题类型太多(例如,是/否、基于值、多项选择、滑块、多级下拉菜单等),我们必须动态创建表单。
我们会在生产中遇到问题,但不会在我们的开发或质量保证环境中遇到问题,类似于您自己;但我们的问题是代码。当我们将应用程序推向生产时,运行的用户数量比我们在 dev/qa 中所能达到的要多得多。
每当我们看到“加载视图状态失败”时,执行以下两种操作之一通常会解决问题:
仅在 INIT 阶段动态创建所有控件。应该在这里完成,以便 ViewState 正常工作而无需额外考虑。 ViewState 在 INIT 完成后加载,并在 PRERENDER 完成后保存。我们可以在 LOAD 阶段创建控件,但接线可能存在细微差别。 (http://msdn.microsoft.com/en-us/library/ms178472.aspx#general_page_lifecycle_stages)
关闭 AJAX 并查看是否可以解决问题(这通常是罪魁祸首)。如果这解决了它,那么我们只需要检查是否没有 AJAX 回发会导致页面更改其布局。 AJAX 调用可能会做一些简单的事情,例如使控件不可见,或使用新 ID 重新呈现控件,从而导致下一次正常回发以检测控件树中的更改。如果我们必须通过 ajax 使控件不可见,我们只需添加属性 ('display','none') 代替。完成更改后,我们重新打开 AJAX。
【讨论】:
我自己可以很容易地重现这个错误,我们的生产服务器还没有对大众开放。同样,我们的代码在大多数情况下会在 init 中创建控件,也有一些特殊情况,但它已经过全面测试。【参考方案3】:这种情况是否适用于各种浏览器?旧版本的 Safari 和一些代理服务器在将 ViewState 传递回服务器时会截断它。
您可能想尝试对视图状态进行分块。您可以通过在 web.config 中的 pages
标记上设置 maxPageStateFieldLength
属性来做到这一点。这里是一个例子
<pages maxPageStateFieldLength="900">
最后,您可能需要考虑完全不使用客户端视图状态。这是一篇实现基于 SQL 的服务器端视图状态提供程序的文章:http://www.codeproject.com/KB/viewstate/ViewStateProvider.aspx
【讨论】:
它发生在 chrome 12、firefox 5 和 ie9 中,我们不支持旧浏览器(最旧的 ie7)。不过我明天会试试看。另外,我已经看到它发生在非常短的视图状态下,并且可以使用视图状态解码器成功解码。 我在下面看到你可以复制这个问题。您是否尝试过在发送到客户端的内容上使用 Fritz Onion 的 ViewState 解码器并确保动态控件不会弄乱 ControlState?仅供参考,ViewState 解码器在这里:pluralsight-training.net/community/media/p/51688.aspx 视图状态是可解码的,并且它包含的数据在最近几次发生错误时是正确的。 我只是放了 maxPageStateFieldLength 来测试它。我自己并没有遇到这个错误,但我认为我已经解决了几次这个错误,所以我要看看错误报告来确定一下。【参考方案4】:我们遇到了一个非常相似的问题:在负载平衡的生产服务器上出现“未能加载视图状态”错误,但我们无法在本地/开发服务器上重现它(即使我们添加了额外的实例以实现负载平衡)开发网站)。
最后我们发现,由于部署过程中的错误,其中一台生产服务器的版本与另一台不同,当用户在一台服务器上启动并继续到另一台服务器(未配置粘性 IP)时,出现了视图状态错误。
【讨论】:
以上是关于无法在 NLB 上加载视图状态的主要内容,如果未能解决你的问题,请参考以下文章