是的我知道这个问题已被多次报道,但我的情况似乎不符合任何建议的解决方案(除非我遗漏了一些东西)。
ASP.NET页面设置(简化)是:用户单击链接(技术上是Infragistics WebDataTree的节点),此操作绑定位于UpdatePanel中的网格(Infragistics WebHierarchicalDataGrid)。
现在这在本地测试系统中运行良好。当部署到生产服务器时 - 它也可以工作 - 大多数情况下,但有时会抛出错误:
无法加载视图状态。 viewstate所在的控制树 正在加载必须与用于保存的控制树匹配 在上一个请求中查看状态
如果生产系统负载较重(更多用户访问它),这似乎更多。同样,我没有构建任何动态控件,只是按钮和按钮单击时填充的网格。
可能导致这种情况的原因是什么?为什么这不会永远发生,但有时呢?知道怎么解决吗?
更新
这是确认的情景
一个会话如何影响另一个会话的视图状态?
更新2
应用程序部署到单个Windows 2008 / IIS7服务器(没有Web场/ Web园,没有负载平衡器)。运行期间不会推出任何更新。
如果单个用户访问它,但是当多个用户访问服务器时,应用程序工作正常 - 最终其中一些用户正在获取ViewState错误(而其他用户仍能正常工作)。他们都在做同样的事情 - 点击触发UpdatePanel内部网格重新绑定的树节点。他们使用不同的浏览器 - IE(9-11),FF,Chrome - 错误可能发生在随机用户/浏览器
哦,我们也没有加密ViewState。
更新3
堆栈追踪:
在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)处 System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState at System.Web.UI.Control.LoadChildViewStateByID(ArrayList childState)at System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Control.LoadChildViewStateByIndex(ArrayList childState) 在System.Web.UI.Control.LoadViewStateRecursive(Object savedState)at System.Web.UI.Page.LoadAllState()at System.Web.UI.Page.ProcessRequestMain(布尔 includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)
更新4
似乎如果我减少每次点击返回的数据大小(例如20行而不是100行),问题就会消失或者出现频率降低很多。
我尝试过操纵ViewState - 例如将其拆分为块,使用session作为ViewState存储来减少实际发布的页面大小 - 没有任何效果。
答案 0 :(得分:6)
关注如何调试我的代码之外的事情以及获取对Infragistics WebHierarchicalDataGrid DLL及其源代码的调试符号的访问权限之后的this advice - 结果是控件抛出了异常 - 它与之无关到了观点。在1元素数组内部代码尝试访问第二个元素,抛出“IndexOutOfBound”异常,该异常经过神奇的转换,向用户抛出“无法加载视图状态”。
Infragistics正在研究错误及其修复方法,但由于我们时间紧迫,我们使用了以下解决方法:如果在异步回发结束时检测到“查看状态”错误 - 我们只需重新加载页面:
Sys.Application.add_load(appLoaded);
function appLoaded(sender, eventArgs) {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequest)
}
function EndRequest(sender, args) {
if (args.get_error() != undefined) {
if (args.get_error().message.indexOf('Failed to load viewstate') != -1) {
setTimeout(function () { location.reload(true) }, 100)
}
}
}
是的我确实意识到这就像用螺丝刀锤击钉子一样优雅,但由于错误是零星的,并且刷新了它 - 这将是必须的。
答案 1 :(得分:4)
您在生产中拥有多少台服务器? 如果您在web.config中设置了machineKey,那么所有服务器都将使用相同的密钥来签署/验证ViewState值?
正如Michael Liu在评论中指出的那样,你不太可能因为machineKey问题而得到控制树错误。我仍然想知道你是否有多个服务器在生产中,因为你可能仍然可能遇到ServerA提供更新版本的代码然后POST回到ServerB但尚未拥有的问题新代码,因此控制树不匹配。如果您在网站上有活跃用户时推出了更改,即使使用单个服务器,这在技术上也可能发生。
答案 2 :(得分:0)
视图状态与会话状态无关。 但是,如果您尝试使用相同浏览器软件的2个实例的websiste,则浏览器具有相同的会话。这适用于IE> = 8,firefox和chrome。 尝试使用2种不同的浏览器(抱歉我的英文不好)
答案 3 :(得分:0)
似乎UpdatePanel导致了viewstate的问题。
更新
要进行调试,我会尝试记录发送给每个客户端的视图状态以及在部分回发期间从客户端收回的视图状态。
您可以将临时存储在与会话关联的数据库服务器上,并在会话结束时清除它们,如果没有异常。然后,如果您遇到此异常,请在数据库中标记它,您可以比较服务器发送给客户端的内容以及回发时收到的内容。您也可以在浏览器中手动加载这些值并重播它们以查看会发生什么。
视图状态正在被客户端破坏,或者您的服务器发送了无效的视图状态。
至少这可以帮助您获得一些数据进行调试。
这是一篇关于更新面板和一些可能有助于解决问题的替代ajax方法的文章:
http://msdn.microsoft.com/en-us/magazine/cc163413.aspx
其他一些可能的帮助:
http://lachlankeown.blogspot.com/2008/04/firefox-refresh-viewstate-updatepanel.html?m=1
http://weblog.west-wind.com/posts/2005/Jul/16/Invalid-ViewState
http://support.microsoft.com/default.aspx?scid=kb;EN-US;829743
答案 4 :(得分:0)
如果使用负载平衡在生产中托管此功能,则当用户从一台服务器更改为另一台服务器时,可能会出现此问题。这里的解决方案通常是在web.config中指定machineKey。 Read more about it here at msdn.
<machineKey
validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F"
validation="SHA1" decryption="AES" />
答案 5 :(得分:0)
您的用户是否实际报告了问题,或者您只是在错误日志中看到它?我在用户取消浏览器上的请求之前看到此错误,导致ASP.NET在尝试解析部分传输的请求时出错。如果视图状态恰好是部分传输,您可能会看到此错误。您的观点和视频越大您拥有的用户越多,您就越有可能看到此错误。您可以放心地忽略此错误。
您可以通过加载包含大量viewstate的页面并取消回发来测试此操作。
答案 6 :(得分:0)
我在某个项目中遇到过类似的问题。问题的原因是我们正在向表控件添加动态控件,然后在提交页面时,表将由不同的控件集填充。在深入研究该问题时,我们发现主要用于上一页的下拉控件,如果在同一位置存在其他控件,则视图状态将失败。
解决方案对我们来说非常简单,因为我们动态创建控件,无论何时每次都创建它们,所以我们只需将ViewState=false
转换为控件(在您的情况下为网格控件)。
根据您的评论,我认为您需要确定跨越会话的内容。当另一个用户登录时,很可能是第一个用户更改的数据。在这种情况下,您还应该考虑设置ViewState=false
,或者将网格绑定到page_Oninit
,这样ViewState就是这样不会发生冲突。
希望这有帮助。
答案 7 :(得分:0)
尝试用ILSpy反编译dll,保存项目,构建它,而不是链接该项目而不是dll。这样,您将获得完整的堆栈跟踪,并且可能更接近异常。
答案 8 :(得分:0)
我遇到了同样的问题,例如:点击一个会重定向我的按钮,然后按下IE上的后退按钮,使用&#34; old&#34; viewstate,而一些内容已经改变。 在IE,Chrome,Firefox上,由于缓存,我遇到了这个问题。
为避免浏览器缓存您的网页,您可以在网址中使用随机参数: 例如:&#34;&amp; ran = 54921356&#34;那将是randomely generatad。 看看这是否有帮助
我不知道你的WebHierarchicalDataGrid是如何绑定的,如果数据可以在回发之后再返回,那么你的更新面包装不应该是视图状态。
我希望这有帮助!
PS:另外,我认为将会话状态存储在会话中是一个坏主意......