如何将下拉列表对应的整数LocationId正确存入ViewModel?
解决DropDownList提交时LocationId始终为0的问题
你的问题根源其实很明确——视图里的select标签name属性和ViewModel的字段不匹配,导致ASP.NET Core的模型绑定找不到对应的值,所以LocationId只能拿到int类型的默认值0。下面是具体的修复步骤和优化建议:
1. 修正select标签的name属性
你在视图里手动给select加了name="locationName",但ViewModel里对应的字段是LocationId。ASP.NET Core的模型绑定是根据表单元素的name属性来匹配ViewModel属性的,所以这个name必须和ViewModel的字段名完全一致。
修改后的视图代码:
<label asp-for="LocationId" class="fg-labels"></label> <select asp-for="LocationId" asp-items="ViewBag.Locations" class="chosen disabledropdowncntrl" data-placeholder="Choose a Location" id="dropDownLocationNames"> <option value=""></option> </select>
- 删掉手动设置的
name="locationName",因为asp-for="LocationId"会自动生成正确的name属性(就是LocationId),手动指定反而会破坏绑定逻辑。 - 同时去掉
for="locationName",asp-for会自动帮你关联label的for属性到select的id,不需要手动写。
2. 确认SelectListItem的Value转换没问题
你已经把LocationId转成字符串了,这一步是对的——HTML里option的value必须是字符串类型,ASP.NET Core的模型绑定会自动把这个字符串转回int类型的LocationId,所以这部分不需要改动。
3. 检查POST方法的模型绑定
确保你的POST方法是直接接收InventoryLocationsHistoryViewModel作为参数,比如:
[HttpPost] public IActionResult Locate(InventoryLocationsHistoryViewModel model) { if (ModelState.IsValid) { // 这里model.LocationId应该就能拿到正确的选中值了 _context.YourTargetTable.Add(model); _context.SaveChanges(); return RedirectToAction("Index"); } // 如果验证失败,记得重新填充下拉列表,避免页面加载后下拉框为空 var locations = _context.InventoryLocations .OrderBy(l => l.LocationName) .Select(us => new SelectListItem { Value = us.LocationId.ToString(), Text = us.LocationName }).ToList(); ViewBag.Locations = locations; return View(model); }
额外的小优化
你可以把填充下拉列表的逻辑抽成一个私有方法,避免在GET和POST方法里重复写代码,比如:
private void LoadLocationsDropdown() { var locations = _context.InventoryLocations .OrderBy(l => l.LocationName) .Select(us => new SelectListItem { Value = us.LocationId.ToString(), Text = us.LocationName }).ToList(); ViewBag.Locations = locations; }
然后在GET方法和POST方法验证失败的分支里调用这个方法就行,代码会更整洁。
内容的提问来源于stack exchange,提问作者user9335731
相关产品推荐
相关产品推荐

