RegisterPostBackControl与跨UpdatePanel的Timer共存失效问题
解决Timer异步回传后GridView下载按钮失效的问题
这个问题我之前也踩过坑,你分析的完全没错——Timer触发的异步回传会重置ScriptManager中已注册的PostBack控件列表,哪怕两个UpdatePanel都是Conditional模式也没用。因为ScriptManager的控件注册是全局状态,只要有异步回传发生,之前注册的控件就会被清空,导致下载按钮点击时走异步回传流程,而下载文件的响应(带二进制流)不符合异步回传要求的JSON格式,就会抛出那个PageRequestManagerParserErrorException。
下面给你两个可行的解决方案,按需选择:
方案一:Timer回传后重新注册下载按钮
核心思路是每次Timer触发异步回传后,重新遍历GridView的所有行,把下载按钮再次注册到ScriptManager中。同时保留原来的RowDataBound注册逻辑,确保首次加载和GridView自身回传时也能正常注册。
后台代码修改:
// 封装一个通用的注册方法 private void ReRegisterDownloadButtons() { if (folderContentGrid.Rows.Count == 0) return; ScriptManager scriptMgr = ScriptManager.GetCurrent(this.Page); foreach (GridViewRow row in folderContentGrid.Rows) { LinkButton downloadBtn = (LinkButton)row.FindControl("lnkDownloadBtn"); // 只注册可见的下载按钮 if (downloadBtn != null && downloadBtn.Visible) { scriptMgr.RegisterPostBackControl(downloadBtn); } } } // 在Timer的Tick事件方法末尾调用注册方法 protected void autoRefreshNotifications(object sender, EventArgs e) { // 你的原有刷新通知逻辑 // ... // 重新注册下载按钮 ReRegisterDownloadButtons(); } // 保留原有的RowDataBound注册逻辑(首次加载/GridView回传时生效) protected void bindDownloadAction(Object sender, GridViewRowEventArgs e) { LinkButton downloadBtn = (LinkButton)e.Row.FindControl("lnkDownloadBtn"); if (downloadBtn != null && downloadBtn.Visible) { ScriptManager scriptMgr = ScriptManager.GetCurrent(this.Page); scriptMgr.RegisterPostBackControl(downloadBtn); } }
这个方案的优点是不会破坏页面的异步体验,下载按钮点击时还是走局部回传(但因为注册了PostBackControl,实际会触发全页回传用于下载,这是正常的),页面其他部分不会刷新。
方案二:强制下载按钮触发全页回传
如果对页面刷新不敏感,可以直接修改LinkButton的客户端点击事件,强制发起全页回传,绕过ScriptManager的异步回传逻辑。
ASPX代码修改:
<asp:LinkButton ID="lnkDownloadBtn" CssClass="block-ui-click" runat="server" data-pid='<%# Eval("UiIndex") %>' OnClick="onClickDownloadBtn" OnClientClick="Sys.WebForms.PageRequestManager.getInstance()._doPostBack('<%= lnkDownloadBtn.UniqueID %>',''); return false;"> <i class="icon-download"></i>Download </asp:LinkButton>
这个方案的优点是代码改动极小,但点击下载按钮时会刷新整个页面,适合对页面流畅度要求不高的场景。
为什么这两种方法有效?
- 方案一:每次异步回传后重新注册控件,让ScriptManager始终知道这个按钮需要触发全页回传(用于输出文件流)。
- 方案二:直接绕过ScriptManager的异步机制,手动触发全页回传,这样响应的文件流就能被浏览器正常解析,不会出现ParserError。
内容的提问来源于stack exchange,提问作者Sunil Chavan
相关产品推荐
相关产品推荐

