ASP.NET MVC:根据可见控件取值存入数据库问题求助
问题分析
问题出在你的两个控件(下拉框和文本框)都绑定到了model.ADSName,这意味着它们生成的HTML元素拥有相同的name属性(都是ADSName)。当表单提交时,浏览器会把这两个控件的值都发送到服务器,ASP.NET MVC的模型绑定器会优先处理先出现的那个控件的值(也就是下拉框),所以不管文本框是否可见,最终都会取下拉框的值。
另外,你原有的JS脚本里存在一个小错误:尝试直接获取dAds(这是一个<div>)的value属性,但实际上应该获取里面的文本框元素的值。
解决方案
我推荐两种可靠的解决方式,你可以根据自己的习惯选择:
方式1:切换时修改控件的name属性
核心思路是:仅让当前可见的控件保留name="ADSName",隐藏的控件移除name属性,这样提交时只有可见控件的值会被发送到服务器。
步骤1:修正HTML中的div样式
把原来的<div id="lstAds" display="block">改成:
<div id="lstAds" style="display:block;">
(因为display是CSS样式属性,需要放在style属性里)
步骤2:更新JavaScript函数
替换原来的ShowHideAds函数:
function ShowHideAds(button) { const dAdsContainer = document.getElementById("dAds"); const lstAdsContainer = document.getElementById("lstAds"); const textInput = dAdsContainer.querySelector('input'); const selectDropdown = lstAdsContainer.querySelector('select'); if (dAdsContainer.style.display === "none") { // 显示文本框,隐藏下拉框 dAdsContainer.style.display = "block"; lstAdsContainer.style.display = "none"; // 给文本框添加name,移除下拉框的name textInput.name = "ADSName"; selectDropdown.removeAttribute("name"); // 清空下拉框的选中值(避免残留值干扰) selectDropdown.selectedIndex = 0; } else { // 隐藏文本框,显示下拉框 dAdsContainer.style.display = "none"; lstAdsContainer.style.display = "block"; // 给下拉框添加name,移除文本框的name selectDropdown.name = "ADSName"; textInput.removeAttribute("name"); // 清空文本框的值 textInput.value = ""; } }
步骤3:初始化页面时设置默认状态
在页面加载时,确保初始显示的下拉框拥有name,隐藏的文本框没有:
window.addEventListener('load', function() { const textInput = document.getElementById("dAds").querySelector('input'); textInput.removeAttribute("name"); });
方式2:使用隐藏字段同步值
核心思路是:用一个绑定到model.ADSName的隐藏字段存储最终要提交的值,下拉框和文本框仅作为输入界面,切换和输入时同步值到隐藏字段。
步骤1:添加隐藏字段
在表单内添加一个隐藏字段(放在<fieldset>里即可):
@Html.HiddenFor(model => model.ADSName)
步骤2:修改下拉框和文本框的绑定
把原来的下拉框和文本框改成不绑定到model.ADSName(避免name冲突):
<!-- 下拉框 --> <div id="lstAds" style="display:block;"> @Html.DropDownList("adsDropdown", ViewBag.adsName as SelectList, "Choose Name") <input type="button" value="+" onclick="ShowHideAds(this)" style="text-align: left; color: #F6855E; background: none; margin: 0; padding: 0; padding-left: 20px; font-weight: bold; border: none; cursor: pointer;" /> </div> <!-- 文本框 --> <div id="dAds" style="display: none;"> @Html.TextBox("adsText") <input type="button" value="x" onclick="ShowHideAds(this)" style="text-align: left; color: #F6855E; background: none; margin: 0; padding: 0; padding-left: 20px; font-weight: bold; border: none; cursor: pointer;" /> </div>
步骤3:更新JavaScript函数及添加同步逻辑
// 切换显示逻辑 function ShowHideAds(button) { const dAdsContainer = document.getElementById("dAds"); const lstAdsContainer = document.getElementById("lstAds"); const hiddenInput = document.getElementById("ADSName"); const textInput = dAdsContainer.querySelector('input'); const selectDropdown = lstAdsContainer.querySelector('select'); if (dAdsContainer.style.display === "none") { dAdsContainer.style.display = "block"; lstAdsContainer.style.display = "none"; // 同步当前隐藏字段的值到文本框 textInput.value = hiddenInput.value; } else { dAdsContainer.style.display = "none"; lstAdsContainer.style.display = "block"; // 尝试同步隐藏字段的值到下拉框(如果存在匹配项) const hasMatchingOption = Array.from(selectDropdown.options).some(opt => opt.value === hiddenInput.value); if (hasMatchingOption) { selectDropdown.value = hiddenInput.value; } else { selectDropdown.selectedIndex = 0; } } } // 下拉框选择时同步到隐藏字段 document.getElementById("lstAds").querySelector('select').addEventListener('change', function() { document.getElementById("ADSName").value = this.value; }); // 文本框输入时同步到隐藏字段 document.getElementById("dAds").querySelector('input').addEventListener('input', function() { document.getElementById("ADSName").value = this.value; });
控制器代码无需修改
你的两个Create方法逻辑是正确的,只要前端传递的ADSName值正确,模型绑定就能正常工作。
内容的提问来源于stack exchange,提问作者Canox
相关产品推荐
相关产品推荐

