You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.Net Core 3.1:如何将下拉列表选中名称插入数据库表

技术问题:下拉列表选中项名称无法插入Stafftbl表,仅保存ID

使用ASP.Net Core搭配Entity Framework Core开发,尝试将下拉列表选中的CountryName、StateName和CityName插入Stafftbl表,但数据仅保存了ID,名称字段为空。

数据库表结构

Country表

CountryIdCountryName
1America
2India

State表

StateIdStateNameCountryId
1California1

City表

CityIdCityNameStateId
1Alameda1

期望的Stafftbl表结构

StaffIdStaffNamePhoneEmailCountryNameStateNameCityName
1Dauda Muhd+12309em@gmail.comAmericaCaliforniaAlameda

现有代码

模型:CascadingModel

public class CascadingModel
{
    public CascadingModel()
    {
        this.Countries = new List<SelectListItem>();
        this.States = new List<SelectListItem>();
        this.Cities = new List<SelectListItem>();
    }

    public List<SelectListItem> Countries { get; set; }
    public List<SelectListItem> States { get; set; }
    public List<SelectListItem> Cities { get; set; }

    public int CountryId { get; set; }
    public int StateId { get; set; }
    public int CityId { get; set; }

    public int StaffId { get; set; }
    public string StaffName { get; set; }
    public string Phone { get; set; }
    public string Email { get; set; }
    public string CountryName { get; set; }
    public string StateName { get; set; }
    public string CityName { get; set; }
}

控制器:DropdownController

public IActionResult Index()
{
        CascadingModel model = new CascadingModel();

        model.Countries = (from c in this.Context.Countries
                           select new SelectListItem
                           {
                               Value = c.CountryId.ToString(),
                               Text = c.CountryName
                           }).ToList();
        return View(model);
    }

    [HttpPost]
    public JsonResult AjaxMethod(string type, int value)
    {
        CascadingModel model = new CascadingModel();

        switch (type)
        {
            case "ddlCountries":
                model.States = (from customer in _context.States
                                where customer.CountryId == value
                                select new SelectListItem
                                {
                                    Value = customer.StateId.ToString(),
                                    Text = customer.StateName
                                }).ToList();
                break;

            case "ddlStates":
                model.Cities = (from customer in _context.Cities
                                where customer.StateId == value
                                select new SelectListItem
                                {
                                    Value = customer.CityId.ToString(),
                                    Text = customer.CityName
                                }).ToList();
                break;
        }

        return Json(model);
    }

    [HttpPost]
    [ActionName("Index")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Index(CascadingModel cascadingModel)
    {
        var model = new StaffDetailVM()
        {
            StaffId = cascadingModel.StaffId,
            StaffName = cascadingModel.StaffName,
            PhoneNumber = cascadingModel.PhoneNumber,
            Email = cascadingModel.Email,
            CountryName = cascadingModel.CountryName,
            StateName = cascadingModel.StateName,
            CityName = cascadingModel.CityName,
        };

        if (model != null)
        {
            await _context.Stafftbl.AddAsync(model);
            await _context.SaveChangesAsync();
        }

        return View(cascadingModel);
    }

视图:Index.cshtml

<form method="post" asp-controller="Dropdown" asp-action="Index" >
<div class="row">
<div class="col-md-4">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="StaffId" class="control-label"></label>
            <input asp-for="StaffId" class="form-control" />
            <span asp-validation-for="StaffId" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="StaffName" class="control-label"></label>
            <input asp-for="StaffName" class="form-control" />
            <span asp-validation-for="StaffName" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="PhoneNumber" class="control-label"></label>
            <input asp-for="PhoneNumber" class="form-control" />
            <span asp-validation-for="PhoneNumber" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Email" class="control-label"></label>
            <input asp-for="Email" class="form-control" />
            <span asp-validation-for="Email" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="CountryId" class="control-label"></label>
            <select id="ddlCountries" name="CountryName" asp-for="CountryId" asp-items="Model.Countries" class="form-control">
               <option value="">--Please select--</option>
            </select>
            <span asp-validation-for="CountryId" class="text-danger"></span>
        </div>
         <div class="form-group">
            <label asp-for="StateId" class="control-label"></label>
            <select id="ddlStates" name="StateName" asp-for="StateId" asp-items="Model.States" class="form-control">
               <option value="">--Please select--</option>
             </select>
            <span asp-validation-for="StateId" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="CityId" class="control-label"></label>
             <select id="ddlCities" name="CityName" asp-for="CityId" asp-items="Model.Cities" class="form-control">
                  <option value="">--Please select--</option>
              </select>
            <span asp-validation-for="CityId" class="text-danger"></span>
        </div>
        <div class="form-group">
            <button type="submit" asp-action="SaveStaff" formnovalidate class="btn btn-primary">Create</button>
        </div>
        <div class="form-group">
            <button type="submit" asp-action="SaveUpdate" formnovalidate class="btn btn-primary">Update</button>
        </div>
        <div class="form-group">
            <input type="submit" value="Insert" class="btn btn-primary" />
        </div>
 </div>
</div>
</form>

问题原因

  1. 视图中下拉列表手动设置了name属性(如name="CountryName"),但asp-for绑定的是CountryId,导致表单提交时仅ID字段能获取值,名称字段为空。
  2. 控制器直接使用模型中空的名称字段赋值给StaffDetailVM,最终数据库保存的就是空值。

解决方案

方案一:通过ID查询名称(推荐,安全可靠)

修改控制器的POST方法,利用接收的ID从数据库查询对应名称,再赋值保存:

[HttpPost]
[ActionName("Index")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(CascadingModel cascadingModel)
{
    // 查询国家名称
    var country = await _context.Countries.FirstOrDefaultAsync(c => c.CountryId == cascadingModel.CountryId);
    // 查询州名称
    var state = await _context.States.FirstOrDefaultAsync(s => s.StateId == cascadingModel.StateId);
    // 查询城市名称
    var city = await _context.Cities.FirstOrDefaultAsync(ci => ci.CityId == cascadingModel.CityId);

    var model = new StaffDetailVM()
    {
        StaffId = cascadingModel.StaffId,
        StaffName = cascadingModel.StaffName,
        PhoneNumber = cascadingModel.Phone, // 注意:CascadingModel中是Phone,需与StaffDetailVM的PhoneNumber对应
        Email = cascadingModel.Email,
        CountryName = country?.CountryName,
        StateName = state?.StateName,
        CityName = city?.CityName,
    };

    if (model != null)
    {
        await _context.Stafftbl.AddAsync(model);
        await _context.SaveChangesAsync();
    }

    return View(cascadingModel);
}

同时修正视图中的下拉列表,移除手动设置的name属性,避免冲突:

<!-- 国家下拉列表 -->
<select id="ddlCountries" asp-for="CountryId" asp-items="Model.Countries" class="form-control">
   <option value="">--Please select--</option>
</select>

<!-- 州下拉列表 -->
<select id="ddlStates" asp-for="StateId" asp-items="Model.States" class="form-control">
   <option value="">--Please select--</option>
</select>

<!-- 城市下拉列表 -->
<select id="ddlCities" asp-for="CityId" asp-items="Model.Cities" class="form-control">
    <option value="">--Please select--</option>
</select>

方案二:前端传递名称(不推荐,易被篡改)

若需从前端传递名称,可添加隐藏字段并通过JavaScript赋值:
在视图中添加隐藏字段:

<input type="hidden" asp-for="CountryName" id="hdnCountryName" />
<input type="hidden" asp-for="StateName" id="hdnStateName" />
<input type="hidden" asp-for="CityName" id="hdnCityName" />

添加JavaScript代码:

// 国家选择事件
document.getElementById('ddlCountries').addEventListener('change', function() {
    var selectedText = this.options[this.selectedIndex].text;
    document.getElementById('hdnCountryName').value = selectedText;
});

// 州选择事件
document.getElementById('ddlStates').addEventListener('change', function() {
    var selectedText = this.options[this.selectedIndex].text;
    document.getElementById('hdnStateName').value = selectedText;
});

// 城市选择事件
document.getElementById('ddlCities').addEventListener('change', function() {
    var selectedText = this.options[this.selectedIndex].text;
    document.getElementById('hdnCityName').value = selectedText;
});

同样需要移除下拉列表中的name属性,确保ID字段正常绑定。

内容的提问来源于stack exchange,提问作者dausa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:45:36