Asp.Net、DropDownList、AutoPostBack 和 Google Chrome

Asp.Net, DropDownList, AutoPostBack and Google Chrome

提问人:tanathos 提问时间:2/4/2009 最后编辑:cgptanathos 更新时间:5/19/2009 访问量:25179

问:

我有一个简单的 asp.net 页面(框架 3.5)和一个 UpdatePanel,其中包含一系列我想异步填充的下拉列表。所有浏览器(Opera、Safari、IE6、IE7、FF3)都运行良好,但在 Chrome 中则不然。

Chrome 似乎忽略了必须发出异步请求的 SelectedIndexChanged 事件。

有人知道一个简单的解决方法吗? 谢谢!

编辑:更多信息

正如我对 Adam Lassek 所说,updatepanel 在单击其中的 asp:Button 后会刷新,但它不适用于下拉列表的事件。SelectedIndexChanged

updatepanel 的设置如下:

<asp:UpdatePanel ID="updPanel" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">

未指定触发器,并且 dropdows 具有集合AutoPostBack="true"

更新:(和重新标记)

经过几次尝试,我发现这不是 UpdatePanel 的问题,但似乎下拉菜单的 AutoPostback 无法正常工作,即使在没有 ScriptManager 和 UpdatePanel 的页面中也是如此...... 我敢肯定,这只是一个关于这个项目的问题,因为如果我从头开始一个新的网站并复制它的结构,在 Chrome 中工作正常...... 我正在尝试逐步删除原始项目中的所有其他内容,以准确找到问题所在。

如果有人在此期间有一些想法......

asp.net 下拉菜单 google-chrome 自动回发

评论


答:

2赞 Adam Lassek 2/4/2009 #1

发生这种情况是因为 MicrosoftAjax.js 执行浏览器检测,并且错误地将 Chrome 检测为 Safari。为了解决此问题,您需要进行以下更改:

添加新的浏览器类型

Sys.Browser = {};
Sys.Browser.InternetExplorer = {};
Sys.Browser.Firefox = {};
Sys.Browser.Safari = {};
Sys.Browser.Opera = {};
Sys.Browser.Chrome = {};

更新 if-then 逻辑以搜索 Chrome

else if (navigator.userAgent.indexOf(' Firefox/') > -1) {
    Sys.Browser.agent = Sys.Browser.Firefox;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Firefox\/(\d+\.\d+)/)[1]);
    Sys.Browser.name = 'Firefox';
    Sys.Browser.hasDebuggerStatement = true;
}

else if (navigator.userAgent.indexOf(' Chrome/') > -1) {
    Sys.Browser.agent = Sys.Browser.Chrome;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Chrome\/(\d+\.\d+)/)[1]);
    Sys.Browser.name = 'Chrome';
    Sys.Browser.hasDebuggerStatement = true;
}
else if (navigator.userAgent.indexOf(' AppleWebKit/') > -1) {
    Sys.Browser.agent = Sys.Browser.Safari;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/ AppleWebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = 'Safari';

请务必在 Safari 之前进行 Chrome 检查。如果您需要帮助将 Framework 脚本替换为自定义版本,请阅读此内容

更新:

我创建了一个测试页,并在其上放置了以下控件:

<asp:ScriptManager ID="scriptManager1" runat="server" />
<asp:UpdatePanel ID="panel1" runat="server" ChildrenAsTriggers="true">
  <ContentTemplate>
    <asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true">
      <asp:ListItem Value="0" Text="Item 1" />
      <asp:ListItem Value="1" Text="Item 2" />
    </asp:DropDownList>
    <asp:Literal ID="litTest" runat="server" />
  </ContentTemplate>
</asp:UpdatePanel>

并编写了以下代码隐藏:

protected override void OnInit(EventArgs e)
{
    ddlTest.SelectedIndexChanged += new EventHandler(ddlTest_SelectedIndexChanged);
    base.OnInit(e);
}

void ddlTest_SelectedIndexChanged(object sender, EventArgs e)
{
    litTest.Text = "Selected: " + ddlTest.SelectedItem.Text;
}

Updatepanel 在 Chrome 中工作正常,无需修改 Ajax 库。所以,我认为是其他原因导致了这个问题。您将需要通过消除过程来隔离问题的原因。从像这个例子这样简单的事情开始,然后一次完成你所拥有的作品。

评论

0赞 tanathos 2/4/2009
我已经尝试了您的建议(并感谢您的回答),但它似乎没有任何改变。我看到如果我在updatepanel中插入一个asp:Button(将ChildrenAsTrigger设置为true),它可以正常工作。但它不适用于 DropDowns 的 SelectedIndexChanged(当然只有 Chrome)..
15赞 joshcomley 2/10/2009 #2

已知与 Ajax.NETChrome & Safari 3 不兼容。

小而快速的测试可能具有欺骗性,因为它看起来可以正常工作,可以按原样与现有的 Ajax.NET 库一起使用。这是因为它设法执行第一个 Ajax 请求并在该请求结束时失败,因此只有当您尝试执行第二个 Ajax 操作时,您才会注意到它失败了。如果在页面上放置一个 UpdateProgress 控件,您会注意到,在第一次请求后,UpdateProgress 控件不会取消。

幸运的是,有一个答案!

最近有一篇很棒的帖子,详细介绍了该怎么做,你可以在这里找到:

http://blog.turlov.com/2009/01/aspnet-ajax-compatibility-patch-for.html

它的总体要点是 Chrome 和 Safari 3 都在其 userAgent 字符串中将自己报告为 WebKit

您需要添加一些 javascript 来帮助 Ajax.NET 框架识别基于 WebKit 的浏览器,如下所示:

if (typeof(Sys.Browser.WebKit) == "undefined") {
    Sys.Browser.WebKit = {};
}

if (navigator.userAgent.indexOf("WebKit/") > -1 ) {
    Sys.Browser.agent = Sys.Browser.WebKit;
    Sys.Browser.version = 
        parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = "WebKit";
}

您需要将其添加到 javascript 文件中,并在 ScriptManager 中引用它:

<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/assets/javascript/WebKit.js" />
    </Scripts>
</asp:ScriptManager>

请注意,您可以将 WebKit.js 保留在程序集中,并使用类似于以下内容的 ScriptReference 标记来引用它:

<asp:ScriptReference Assembly="Scripts" Name="Scripts.webkit.js" />

完成所有这些操作后,如果可能的话,停止使用 WebForms 和 Ajax.NET,并使用 MVC 和 jQuery :)

评论

0赞 Ole Lynge 5/29/2009
谢谢!这解决了我在 Chrome 的 UpdatePanel 中分页 GridView 的问题。
0赞 Bayard Randel 8/19/2009
“如果可能的话,停止使用WebForms和 Ajax.NET,并使用MVC和jQuery。圣人的建议,但与此同时,这个修复程序效果很好。谢谢好心的先生。
0赞 xr280xr 10/14/2011
我尝试了一下,将脚本编译到我的组合中,并通过在第二个 if 块中添加一个超级烦人的警报('')来验证它是否正在执行。但是在加载页面后,我检查了浏览器代理和名称,并将其设置为Chrome。似乎脚本运行得太早,并且将其更改覆盖回 Chrome?我将它与加载到 SharePoint 2007 网站中的 UserControl 一起使用。对此有什么想法吗?
0赞 aturlov 3/13/2009 #3

使用 MVC 和 jQuery 而不是 WebForms 和 ASP.NET AJAX 不是一个合适的建议。人们应该了解可供选择的技术和方法的所有优缺点。

首先,MVC 是一种设计模式,与提到的特定框架无关。您可以使用 WebFroms 轻松实现 MVC 模式。MVC for ASP.NET 和 WebForms 有许多不同的实现。

其次,jQuery是一个很棒的JavaScript库,它不允许与服务器端 ASP.NET 功能进行任何集成,也不利用服务器端功能,而AJAX框架 ASP.NET AJAX框架是 ASP.NET 3.5+的标准配置,并充分利用 ASP.NET 功能,如服务器端标记、ScriptManager控制、服务器端脚本组合、本地化和全球化等。

第三,jQuery可以很容易地与 ASP.NET 和 ASP.NET AJAX框架结合使用,从而增强客户端编程。Microsoft 已经宣布 jQuery 将与下一个 ASP.NET 4.0 一起发布,现在您可以手动将其添加到您的项目中。

0赞 Jonathan Schuster 5/1/2009 #4

我今天刚刚遇到了类似的问题(尽管我没有使用 Ajax),并找到了修复程序。请参阅这篇博文的第三条评论。

0赞 Jonathan Parker 5/1/2009 #5

我有同样的问题。我在ajax回发中有一个下拉列表,需要在所选索引更改时进行更新。它也适用于新项目中的基本页面。

添加其他答案中提到的 Webkit 脚本后,我仍然遇到同样的问题,并且在 Chrome 中运行 javascript 调试器时出现以下错误:

未捕获的异常 ReferenceError:未定义 evt

更新:解决方案

我发现在我的情况下,是 CustomValidator 干扰了事件处理程序。将 EnableClientScript 设置为 false 修复了该问题。

0赞 dotnetguts 5/19/2009 #6

您可以查看解决方案

http://dotnetguts.blogspot.com/2009/05/dropdownlist-autopostback-problem-with.html