使用ASP.NET AJAX / ICallbackEventHandler跟踪状态

我在ASP.NET AJAX页面中维护状态时遇到问题。简短版本:我需要一些方法来在进行异步回调后更新页面ViewState,以反映服务器在异步调用期间所做的任何状态更改。

这似乎是一个常见问题,但我会描述我的场景以帮助解释:

我有一个类似网格的控件,它具有一些JavaScript增强功能 - 即拖放列和行的功能。当一个列或行被放到一个新位置时,会调用AJAX方法来通知控制服务器端并激发相应的服务器端事件(“OnColumnMoved”或“OnRowMoved”)。

默认情况下,ASP.NET AJAX调用将整个页面作为请求发送。通过这种方式页面经历了一个完整的生命周期,视图状态被持久化并且在调用RaiseCallbackEvent方法之前恢复控件的状态。

However, since the AJAX call does not update the page, the ViewState reflects the original state of the control, even after the column or row has been moved. So the second time a client-side action occurs, the AJAX request goes to the server and the page & control are built back up again to reflect the first state of the control, not the state after the first column or row was moved.

这个问题延伸到许多影响。例如,如果我们有一个客户端/ AJAX操作来向网格添加一个新项目,然后拖动一行,则网格将在服务器端构建,其中一个项目少于客户端项目。

And finally & most seriously for my specific example, the actual data source object we are acting upon is stored in the page ViewState. That was a design decision to allow keeping a stateful copy of the manipulated data which can either be committed to DB after many manipulations or discarded if the user backs out. That is very difficult to change.

所以,再次,我需要一种方法来在页面ViewState在AJAX方法触发后在回调中更新。

0
额外 编辑
意见: 1

5 答案

我确实发现了您提供的这两个链接,但正如他们所指出的那样,他们只是简单地描述问题,而不是解决问题。博客文章的作者通过使用不同的ViewState提供程序提出了一种解决方法,但不幸的是,在这种情况下这不是一种可能性......我真的需要单独留下ViewState的细节,并且仅仅关注正在做的事情盒子外面。

0
额外

我用 Telerik的RadAjaxManager 。它工作得非常好,基本上你注册了每个可能调用回发的控件,然后注册每个应该在异步执行回发之后重新绘制的控件。 RadAjaxManager将在异步回发之后更新DOM,并重写ViewState和所有受影响的控件。在Reflector中窥视之后,它在引擎盖下看上去有点诡异,但它适合我的目的。

0
额外

无论如何,如果你已经对ViewState进行了洗牌,你还可以使用UpdatePanel。它的部分回传自动更新页面的ViewState。

0
额外

我不明白为什么你会使用自定义控件,当内置的ASP.NET AJAX UpdatePanel做同样的事情。

它只会增加更多的复杂性,减少支持,并使其他人更难以处理您的应用程序。

0
额外

看看这篇博文:调整ICallbackEventHandler和Viewstate 。作者似乎正在处理您正在经历的情况:

因此,在使用ICallbackEventHandler时,有两个障碍需要克服才能更新状态管理的回调。首先是只读视图状态的问题。另一个实际上是在触发回调之前注册用户对页面所做的更改。

有关如何解决此问题的建议,请参阅博客文章。同时查看这个论坛帖子,它也讨论了同样的问题。

0
额外