提问人:tanathos 提问时间:2/4/2009 最后编辑:cgptanathos 更新时间:5/19/2009 访问量:25179
Asp.Net、DropDownList、AutoPostBack 和 Google Chrome
Asp.Net, DropDownList, AutoPostBack and Google Chrome
问:
我有一个简单的 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 中工作正常...... 我正在尝试逐步删除原始项目中的所有其他内容,以准确找到问题所在。
如果有人在此期间有一些想法......
答:
发生这种情况是因为 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 库。所以,我认为是其他原因导致了这个问题。您将需要通过消除过程来隔离问题的原因。从像这个例子这样简单的事情开始,然后一次完成你所拥有的作品。
评论
已知与 Ajax.NET 和 Chrome & 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 :)
评论
使用 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 一起发布,现在您可以手动将其添加到您的项目中。
我今天刚刚遇到了类似的问题(尽管我没有使用 Ajax),并找到了修复程序。请参阅这篇博文的第三条评论。
我有同样的问题。我在ajax回发中有一个下拉列表,需要在所选索引更改时进行更新。它也适用于新项目中的基本页面。
添加其他答案中提到的 Webkit 脚本后,我仍然遇到同样的问题,并且在 Chrome 中运行 javascript 调试器时出现以下错误:
未捕获的异常 ReferenceError:未定义 evt
更新:解决方案
我发现在我的情况下,是 CustomValidator 干扰了事件处理程序。将 EnableClientScript 设置为 false 修复了该问题。
您可以查看解决方案
http://dotnetguts.blogspot.com/2009/05/dropdownlist-autopostback-problem-with.html
评论