C# MVC下拉列表选择项存为字符串时遇类型错误求助
问题解决:InvalidOperationException 下拉列表数据源类型不匹配
问题原因
POST请求中ModelState验证失败返回视图时,未重新填充下拉列表的数据源(ViewBag.TrucksList)。当ViewBag中无对应数据时,DropDownListFor会默认尝试使用ViewData["TruckName"]作为数据源,但该值是绑定的字符串类型,不符合IEnumerable<SelectListItem>的要求,因此抛出异常。
核心修复步骤
1. 修改POST的Create方法
在ModelState无效返回视图前,重新调用填充下拉列表的方法,确保ViewBag有正确的数据源:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("TruckName,ComponentTested,TestType,TestDate,Score")] TruckTest truckTest) { if (ModelState.IsValid) { _context.Add(truckTest); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // 验证失败时重新填充下拉列表 PopulateTrucksDropDownList(); return View(truckTest); }
2. 优化:改用强类型模型传递数据源(可选但推荐)
依赖ViewBag容易出现上下文丢失问题,建议将下拉数据源绑定到模型属性:
修改模型类
public class TruckTest { [Key] public string TruckName { get; set; } public string ComponentTested { get; set; } public string TestType { get; set; } public DateTime TestDate { get; set; } public int Score { get; set; } // 用于下拉列表的数据源 public IEnumerable<SelectListItem> TruckOptions { get; set; } }
调整Populate方法
private void PopulateTrucksDropDownList(TruckTest model = null) { // 替换为实际的卡车数据源查询逻辑 var trucksList = _context.Trucks .OrderBy(t => t.Name) .Select(t => new SelectListItem { Text = t.Name, Value = t.Name }) .ToList(); if (model != null) { model.TruckOptions = trucksList; } else { ViewBag.TrucksList = trucksList; } }
修改POST方法与视图
POST方法中传递模型到Populate方法:
if (ModelState.IsValid) { // 保存逻辑 } PopulateTrucksDropDownList(truckTest); return View(truckTest);
视图改用模型属性作为数据源:
@Html.DropDownListFor(model => model.TruckName, Model.TruckOptions, "Select a truck", new { @class = "form-control" } ) @Html.ValidationMessageFor(model => model.TruckName, "", new { @class = "text-danger" })
额外注意事项
- 确保
PopulateTrucksDropDownList中的数据源查询正确,能生成有效的SelectListItem集合。 - 由于
TruckName是主键,建议添加ModelState验证,避免重复提交相同卡车名称的记录。
内容的提问来源于stack exchange,提问作者adamr
相关产品推荐
相关产品推荐

