ASP.NET Ajax在iPhone/iPad上突然停止了postback

7

我有一个使用更新面板和一些按钮的Asp.Net 4.0网站/控制界面。更新面板连接到一个定时器,每5秒执行一次,导致部分回发。这些按钮切换一些设置,然后通过类似于以下调用强制更新更新面板:

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm._doPostBack('<%= UpdatePanel.ClientID %>', '');
return true;

该网站在IE/Firefox上运行良好,在Safari移动设备(iPhone/iPad)上也能正常运行,但在移动设备上,提交回发(postback)会随机而又无声地停止工作。我认为这可能与节省电池有关,当Safari处于空闲状态时,它会关闭部分的提交回发(postback)。问题在于,当用户返回网站时,提交回发(postback)完全关闭,并且定时器和按钮都不再引起任何提交回发(postback)。(我已经监控了服务器上的网络流量以验证这一点)。即使用户多次刷新网站,部分提交回发(postback)也不再起作用,它只是停止向服务器发送数据。然后,突然间,没有任何特定的原因,提交回发(postback)又开始工作了。这种停机时间通常长达10分钟,这完全使我的网站失去了其目的。
考虑到提交回发(postback)需要很长时间才能重新开始工作,我想知道是否有任何客户端或IIS方面的设置可以进行调整?
该网站仅在我的客户设备上运行,不对外公开,因此如果客户端有任何设置可以调整,我愿意尝试。
我真的对此感到困惑,还没有找到触发“错误”的方法,它只是偶尔发生。任何建议和提示都将不胜感激。

更新:

增加了一些错误处理,当回发失败时,我(不是一致地)收到以下消息:

该页面正在执行异步回发,但 ScriptManager.SupportPartialRendering 属性设置为 false。请确保在回发期间将属性设置为 true。

很奇怪的是,在第一种情况下,该属性显然为 true,否则回发永远不会起作用,这并非事实。


更新2: 发现以下博客文章建议在web.config中更改browserCap设置。正在尝试此方法。将会回报结果。仍然欢迎其他建议。 ASP.NET 4 BrowserCaps(或:他们在想什么?) 以上操作会在Safari移动版全屏模式下禁用JavaScript(从主屏幕运行)。以下文章提供了解决此问题的方法。 Gotcha:iPad与ASP.NET
1个回答

6
在我的问题中,“更新2”下的发现解决了这个问题。显然,Safari UserAgents偶尔被识别为Mozilla 0.0,如以下博客文章所示:ASP.NET 4 BrowserCaps (or: what were they thinking?)

第一个 WTF 是,如果它检测到来自根据BrowserCaps不支持异步postback的浏览器的异步postback,.NET框架实际上会抛出异常。就好像他们认为他们知道谁能够异步postback,即使有压倒性的证据证明相反...

下一个 WTF 要难得多。为什么 Safari UserAgents 偶尔被识别为 Mozilla 0.0,为什么我甚至无法重现使用刚从异常中复制的 UserAgent 字符串的问题?

答案在于

<browserCaps userAgentCacheKeyLength="64" />

用户代理缓存键长度的默认设置是获取UserAgent字符串的前64个字符。...

并且页面往下滑:

将userAgentCacheKeyLength设置为256解决了该问题,即使还有一些被识别为Mozilla 0.0的UserAgent字符串。至少现在是一致的。

所以,在Web.Config中加入<browserCaps userAgentCacheKeyLength="256" />可以解决这个问题。
不幸的是,当Safari浏览器在全屏模式下使用(链接保存在主屏幕上)时,这会导致另一个问题。在全屏模式下,Safari使用不同的HTTP用户代理字符串,而ASP.NET不再将浏览器识别为Safari,而是将其识别为没有功能的通用浏览器,例如JavaScript和JQuery将停止工作。这在Gotcha: iPad versus ASP.NET中更详细地说明了。解决方案是在每个网站的Page_Init中放置以下内容。不太优雅,但它与上述内容一起工作:
protected void Page_PreInit(object sender, EventArgs e)
{
   if (Request.UserAgent != null && Request.UserAgent.IndexOf("AppleWebKit", StringComparison.CurrentCultureIgnoreCase) > -1)
   {
      this.ClientTarget = "uplevel";
   }
}

感谢 @Avada Kedavra!我也遇到了完全相同的问题,<browserCaps userAgentCacheKeyLength="256" /> 解决了它。非常感激!我还没有将其放在 Page_PreInit 部分,这能够仅仅放在 MasterPage 上以适用于所有页面吗? - Mark Pieszak - Trilon.io
@mcpDESIGNS:我还没有尝试过,但对任何能使解决方案更简洁、代码更少的方法都很感兴趣。你用你所建议的方法取得了什么成功吗? - Avada Kedavra
我需要对它进行更多的测试,然后再告诉你!我只是想说把 Page_PreInit 放在母版页上会使得你不必将其复制/粘贴到每个子页面上。 - Mark Pieszak - Trilon.io
是的,我明白了,我很遗憾还没有测试过。但这似乎是对上面的一个合理改进。 - Avada Kedavra
它在我的系统中无法工作。IsPostBack始终为false。 - Rehan Parvez
将具有256个字符的用户代理的browserCaps添加解决了一些设备的问题,但对于在其iPad / iPhone上同时使用Chrome和Safari的设备则无效。是否有任何方法可以清除这些缓存的用户代理? 在两个浏览器上清除浏览器缓存似乎不起作用。 - Pallavi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接