ASP.NET中AjaxToolkit CascadingDropDown仅IE可用,其他浏览器失效求助
问题分析
核心问题是AjaxControlToolkit 3.0的CascadingDropDown控件仅在IE正常工作,Chrome等现代浏览器中子下拉框为空,且IE操作后其他浏览器才恢复正常。这主要是旧版本控件的跨浏览器JS兼容缺陷,加上WebService参数解析的低级错误导致的。
1. 先修复WebService的致命参数错误
你的WebService代码里解析knownCategoryValues时用了kv.ContainsKey("undefined"),这完全不符合CascadingDropDown的参数传递规则:
// 错误代码 if (!kv.ContainsKey("undefined") || !Int32.TryParse(kv["undefined"], out BudgetExpenseHeadID)) { return null; }
CascadingDropDown会把你设置的Category="BudgetExpenseHead"作为键来传递父控件的选中值,正确写法应该用这个Category名称作为Key:
// 修正后的代码 Int32 BudgetExpenseHeadID; if (!kv.ContainsKey("BudgetExpenseHead") || !Int32.TryParse(kv["BudgetExpenseHead"], out BudgetExpenseHeadID)) { return null; }
旧版IE对参数传递有容错机制,而Chrome等浏览器严格按规则传值,导致之前的代码直接返回null,子下拉框自然没有数据。
2. 升级AjaxControlToolkit到兼容.NET 3.5的最新稳定版
AjaxControlToolkit 3.0是2009年的老旧版本,对现代浏览器兼容极差。可以升级到7.1213版本(支持.NET Framework 3.5的最后几个稳定版本之一):
- 卸载项目中旧的AjaxControlToolkit引用
- 通过NuGet命令安装:
Install-Package AjaxControlToolkit -Version 7.1213 - 替换页面中
ajaxToolkit命名空间引用(如果有版本变更)
升级后控件的JS逻辑会修复大量跨浏览器兼容问题,比如XHR请求处理、DOM操作的兼容性。
3. 临时修复控件JS兼容性(无法升级时)
如果暂时不能升级控件,可以手动修改CascadingDropDown的客户端脚本:
- 找到项目引用的
AjaxControlToolkit.js或CascadingDropDown.js文件 - 检查XHR响应解析代码,旧版控件可能用了IE独有的
responseText解析方式,改成标准的JSON解析 - 检查父控件值变化的事件绑定,确保同时支持标准DOM事件和IE旧事件
4. 备选方案:替换为原生AJAX实现(彻底解决兼容)
如果升级控件仍有问题,直接放弃旧控件,用jQuery+ASP.NET AJAX实现级联下拉:
前端代码修改
<asp:DropDownList runat="Server" CssClass="frmTextBox" ID="ddlBudgetExpenseHead" Width="600px" /> <asp:DropDownList runat="Server" CssClass="frmTextBox" ID="ddlBudgetExpenseHeadDetail" Width="400px" AutoPostBack="True" onselectedindexchanged="ddlBudgetExpenseHeadDetail_SelectedIndexChanged" /> <script type="text/javascript"> $(function() { $("#<%= ddlBudgetExpenseHead.ClientID %>").change(function() { var headId = $(this).val(); var $detailDdl = $("#<%= ddlBudgetExpenseHeadDetail.ClientID %>"); $detailDdl.empty().append('<option value="">[Loading Budget Expense Head Groups(s)]</option>'); $.ajax({ url: '<%= ResolveUrl("~/WebService/wbsBudgetReferenceHead.asmx/GetBudgetReferenceHeadDetailListByBudgetExpenseHeadID") %>', type: 'POST', contentType: 'application/json; charset=utf-8', data: JSON.stringify({ BudgetExpenseHeadID: headId }), success: function(response) { var data = response.d; $detailDdl.empty().append('<option value="">All Budget Expense Head Groups(s)</option>'); $.each(data, function(i, item) { $detailDdl.append('<option value="' + item.Value + '">' + item.Text + '</option>'); }); }, error: function() { $detailDdl.empty().append('<option value="">Error loading data</option>'); } }); }); }); </script>
WebService代码调整(直接接收ID参数)
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public List<NameValuePair> GetBudgetReferenceHeadDetailListByBudgetExpenseHeadID(int BudgetExpenseHeadID) { SMART.DAL.BMS.BudgetExpenseHeadDetail objBudgetExpenseHeadDetail = new SMART.DAL.BMS.BudgetExpenseHeadDetail(); DataTable dt = objBudgetExpenseHeadDetail.SelectByBudgetExpenseHeadID(BudgetExpenseHeadID); List<NameValuePair> values = new List<NameValuePair>(); foreach (DataRow dr in dt.Rows) { values.Add(new NameValuePair { Text = dr["BudgetExpenseHeadDetailDescription"].ToString(), Value = dr["BudgetExpenseHeadDetailID"].ToString() }); } return values; } // 新增简单的实体类 public class NameValuePair { public string Text { get; set; } public string Value { get; set; } }
这种方式完全脱离旧控件限制,兼容所有现代浏览器。
额外检查点
- 确保页面头部添加
<meta http-equiv="X-UA-Compatible" content="IE=edge" />,强制IE使用标准渲染模式 - 检查
web.config是否配置了ASP.NET AJAX的处理程序:
<system.web> <httpHandlers> <add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/> </httpHandlers> </system.web>
内容的提问来源于stack exchange,提问作者Muhammad zubair sultan
相关产品推荐
相关产品推荐

