Ajax填充的Dropdown触发SelectedIndexChanged后数据丢失的服务器端解决问询
服务器端解决UpdatePanel中Ajax填充DropDownList回发后数据丢失问题
问题根源
客户端通过Ajax添加的DropDownList选项不会被ASP.NET的ViewState记录,当UpdatePanel触发局部回发(SelectedIndexChanged事件触发)时,服务器会重新初始化DropDownList,若未重新绑定数据,就会导致选项丢失。
解决方案一:复用业务逻辑,回发时重新绑定
核心思路是将WebMethod中的数据获取逻辑抽离为可复用的非静态方法,在页面回发时(包括局部回发)重新绑定DropDownList,同时保留用户选中项。
1. 抽离数据获取逻辑
修改后台代码,把WebMethod中的业务逻辑抽成非静态方法,同时改造原WebMethod调用该方法:
// 抽离的非静态方法,用于服务器端绑定和WebMethod调用 private List<AutoTradeExpDateRes> GetExpDateList() { List<AutoTradeExpDateRes> autoTradeExpDateRes = new List<AutoTradeExpDateRes>(); try { string expdateres = GetAPIResponse("ssss://xxx.com/fns.aspx?otype=analyse_expdate&uid=62&symbol=nifty&instrument=ce"); var expdatelst = JsonConvert.DeserializeObject<List<AutoTradeExpDateRes>>(expdateres); if (expdatelst != null && expdatelst.Count > 0) { for (int i = 0; i < expdatelst.Count; i++) { autoTradeExpDateRes.Add(new AutoTradeExpDateRes { ID = i, ExpDate = Convert.ToString(expdatelst[i].ExpDate) }); } } return autoTradeExpDateRes; } catch (Exception) { throw; } } // 修改原WebMethod,调用抽离的方法 [WebMethod] public static List<AutoTradeExpDateRes> PopulateExpDate() { AutoTrade pageInstance = (AutoTrade)HttpContext.Current.Handler; return pageInstance.GetExpDateList(); }
2. 页面回发时重新绑定DropDownList
在Page_Load事件中处理回发逻辑,调用绑定方法:
protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { // 局部回发时重新绑定DropDownList BindExpDateDropDown(); } } // 封装DropDownList绑定方法,保留选中项 private void BindExpDateDropDown() { var expDateList = GetExpDateList(); // 保存当前选中值 string selectedValue = AutoTradeTop_expdate.SelectedValue; AutoTradeTop_expdate.DataSource = expDateList; AutoTradeTop_expdate.DataValueField = "ID"; AutoTradeTop_expdate.DataTextField = "ExpDate"; AutoTradeTop_expdate.DataBind(); // 恢复选中项 if (!string.IsNullOrEmpty(selectedValue)) { var targetItem = AutoTradeTop_expdate.Items.FindByValue(selectedValue); if (targetItem != null) { targetItem.Selected = true; } } }
3. 处理SelectedIndexChanged事件
此时可以正常获取选中值,后续联动其他下拉列表的逻辑直接写在这里即可:
protected void AutoTradeTop_expdate_SelectedIndexChanged(object sender, EventArgs e) { string selectedId = AutoTradeTop_expdate.SelectedValue; // 这里编写联动逻辑,例如绑定其他DropDownList // BindRelatedDropDown(selectedId); }
解决方案二:缓存数据到Session,减少API调用
如果API调用耗时,可将数据缓存到Session中,避免重复请求:
private List<AutoTradeExpDateRes> GetExpDateList() { // 先从Session读取缓存数据 List<AutoTradeExpDateRes> expDateList = Session["ExpDateList"] as List<AutoTradeExpDateRes>; if (expDateList == null) { // 缓存不存在时调用API获取数据 expDateList = new List<AutoTradeExpDateRes>(); try { string expdateres = GetAPIResponse("ssss://xxx.com/fns.aspx?otype=analyse_expdate&uid=62&symbol=nifty&instrument=ce"); var expdatelst = JsonConvert.DeserializeObject<List<AutoTradeExpDateRes>>(expdateres); if (expdatelst != null && expdatelst.Count > 0) { for (int i = 0; i < expdatelst.Count; i++) { expDateList.Add(new AutoTradeExpDateRes { ID = i, ExpDate = Convert.ToString(expdatelst[i].ExpDate) }); } } // 将数据存入Session,设置过期时间 Session["ExpDateList"] = expDateList; Session.Timeout = 20; // 20分钟过期 } catch (Exception) { throw; } } return expDateList; }
注意事项
- 确保母版页的
ScriptManager已开启EnablePartialRendering(默认值为true),保证UpdatePanel正常工作 - 若母版页已有ScriptManager,子页面无需重复添加,避免冲突
- 如需强制刷新数据,可清空Session中的
ExpDateList缓存
内容的提问来源于stack exchange,提问作者ashok
相关产品推荐
相关产品推荐

