Asp.NET DropDownList表单提交后为空,求数据持久化方案
解决ASP.NET DropDownList动态填充后回发为空的问题
我来帮你分析下这个问题:你通过jQuery动态给DropDownList添加了选项,但表单回发后它又变回空,核心原因是ASP.NET的ViewState不会自动保存客户端动态添加的控件选项。服务器端在回发时,只会识别它初始渲染或服务器端添加的选项,客户端新增的选项不在ViewState里,所以回发后DropDownList会回到初始状态——哪怕你注册了事件验证,也只是确保提交的选中值合法,但服务器端没有对应的选项可以显示。
下面给你几个可行的解决方案,你可以根据自己的场景选择:
方案1:回发时在服务器端重新绑定数据源
如果填充DropDownList的dataList在服务器端回发时仍能获取到(比如从数据库、Session或其他服务端存储读取),这是最简单的方法:
在Page_Load方法中,回发时重新给DropDownList添加选项,并恢复选中值:
protected void Page_Load(object sender, EventArgs e) { if (IsPostBack) { // 重新获取填充DropDownList的数据源,和你Render方法里的dataList一致 foreach (var item in dataList) { DropDownListReason.Items.Add(new ListItem(item.Description, item.Id.ToString())); } // 从Request中恢复选中的值(因为回发时选中值会被提交到服务器) var selectedValue = Request[DropDownListReason.UniqueID]; if (!string.IsNullOrEmpty(selectedValue)) { DropDownListReason.SelectedValue = selectedValue; } } }
这样服务器端在回发时会重新生成所有选项,DropDownList就能正常显示了。
方案2:用HiddenField保存选项信息,回发时重建
如果你的数据源只能在客户端获取(比如纯前端接口返回),可以把动态添加的选项信息存在HiddenField里,回发时服务器端读取并重建选项:
步骤1:添加HiddenField控件
<asp:HiddenField ID="hfDropDownOptions" runat="server" />
步骤2:修改jQuery代码,保存选项到HiddenField
// 先清空HiddenField $("#<%= hfDropDownOptions.ClientID %>").val(''); var optionList = []; $.each(response, function (key, value) { if (value.requiresDescription) { requiresDescription.push(value.id); } // 创建选项并添加到DropDownList var option = $("<option />").val(value.id).text(value.description); $("#<%= DropDownListReason.ClientID %>").append(option); // 把选项信息存到数组(转成JSON字符串) optionList.push(JSON.stringify({ id: value.id, description: value.description })); }); // 把数组转成字符串存入HiddenField $("#<%= hfDropDownOptions.ClientID %>").val(optionList.join('|'));
步骤3:服务器端回发时重建选项
// 先定义一个对应选项的模型类 public class DropDownOption { public int Id { get; set; } public string Description { get; set; } } protected void Page_Load(object sender, EventArgs e) { if (IsPostBack && !string.IsNullOrEmpty(hfDropDownOptions.Value)) { var optionStrings = hfDropDownOptions.Value.Split('|'); foreach (var optStr in optionStrings) { var option = Newtonsoft.Json.JsonConvert.DeserializeObject<DropDownOption>(optStr); DropDownListReason.Items.Add(new ListItem(option.Description, option.Id.ToString())); } // 恢复选中值 var selectedValue = Request[DropDownListReason.UniqueID]; if (!string.IsNullOrEmpty(selectedValue)) { DropDownListReason.SelectedValue = selectedValue; } } }
方案3:用服务器端AJAX(UpdatePanel)填充选项
如果场景允许,尽量在服务器端触发填充操作,这样ViewState会自动保存选项状态,这是最贴合ASP.NET生命周期的做法:
步骤1:用UpdatePanel包裹相关控件
<asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <!-- 你的两个文本框,设置AutoPostBack=true --> <asp:TextBox ID="TextBox1" runat="server" AutoPostBack="true" OnTextChanged="TextBox_TextChanged"></asp:TextBox> <asp:TextBox ID="TextBox2" runat="server" AutoPostBack="true" OnTextChanged="TextBox_TextChanged"></asp:TextBox> <asp:DropDownList ID="DropDownListReason" runat="server" CssClass="span8"> <asp:ListItem Text="Select a reason" Value=""></asp:ListItem> </asp:DropDownList> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="TextBox1" EventName="TextChanged" /> <asp:AsyncPostBackTrigger ControlID="TextBox2" EventName="TextChanged" /> </Triggers> </asp:UpdatePanel>
步骤2:服务器端文本框变更事件中填充选项
protected void TextBox_TextChanged(object sender, EventArgs e) { // 检查两个文本框是否都已填写完成 if (!string.IsNullOrEmpty(TextBox1.Text) && !string.IsNullOrEmpty(TextBox2.Text)) { // 获取数据源并填充DropDownList foreach (var item in dataList) { DropDownListReason.Items.Add(new ListItem(item.Description, item.Id.ToString())); } } }
这种方式下,选项是服务器端添加的,ViewState会自动保存,回发时DropDownList的状态会完整保留,不需要额外处理。
内容的提问来源于stack exchange,提问作者LP. Gonçalves
相关产品推荐
相关产品推荐

