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

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

Tracking state using ASP.NET AJAX / ICallbackEventHandler

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

这似乎是一个常见问题,但是我将描述我的情况以帮助解释:

我有一个类似于网格的控件,该控件具有一些JavaScript增强功能-即拖放列和行的能力。当列或行放到新位置时,将调用AJAX方法以通知控制服务器端并触发相应的服务器端事件(" OnColumnMoved"或" OnRowMoved")。

默认情况下,ASP.NET AJAX调用将整个页面作为请求发送。这样,页面将经历完整的生命周期,在调用RaiseCallbackEvent方法之前,视图状态将保持不变,并且控件的状态将恢复。

但是,由于AJAX调用不会更新页面,因此即使在移动列或行之后,ViewState也会反映控件的原始状态。因此,第二次执行客户端操作时,AJAX请求将发送到服务器,并且再次构建页面和控件以反映控件的第一状态,而不是第一列或第一行被移动后的状态。

这个问题扩展到许多含义。例如,如果我们有一个客户端/ AJAX操作将一个新项目添加到网格中,然后拖动一行,则在服务器端构建网格时会比客户端少一个项目。

最后,对于我的特定示例来说,也是最重要的一点,我们要操作的实际数据源对象存储在页面ViewState中。这是一项设计决策,允许保留已操纵数据的有状态副本,该副本可以在多次操纵后提交给DB,如果用户退出则可以丢弃。这很难改变。

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


如果您已经在改组ViewState,则最好使用UpdatePanel。其部分回发将自动更新页面的ViewState。


查看此博客文章:调整ICallbackEventHandler和Viewstate。作者似乎正在解决您正在遇到的情况:

So when using ICallbackEventHandler you have two obstacles to overcome to have updated state management for callbacks. First is the problem of the read-only viewstate. The other is actually registering the changes the user has made to the page before triggering the callback.

有关如何解决此问题的建议,请参阅博客文章。还可以查看此论坛帖子,其中讨论了同样的问题。


当内置的ASP.NET AJAX UpdatePanel执行相同的操作时,我不明白为什么要为此使用自定义控件。

它只会增加更多的复杂性,给您更少的支持,并使其他人在您的应用程序上工作变得更加困难。


我用Telerik的RadAjaxManager找到了一个相当优雅的解决方案。它工作得很好。本质上,您注册了每个可能调用回发的控件,然后注册了在异步执行回发后应重新绘制的每个控件。 RadAjaxManager将在异步回发后更新DOM,并重写ViewState和所有受影响的控件。在Reflector中进行了窥视之后,它看起来有点杂乱无章,但是很适合我的目的。


我实际上找到了您提供的两个链接,但是如前所述,它们只是描述问题而不是解决问题。博客文章的作者提出了使用其他ViewState提供程序的解决方法,但不幸的是,在这种情况下这是不可能的...我真的需要不理会ViewState的详细信息,而只是想了解正在做的事情盒子外面。


推荐阅读