Asp.Net Core多选SelectList提交后多对多关联技能计数为0问题
问题根因
你前端多选下拉框提交的是选中的技能ID的整数数组,但User实体的UserSkills属性是IList<UserSkill>类型,ASP.NET Core默认的模型绑定器无法自动将字符串格式的ID数组直接转换为UserSkill对象集合,所以绑定失败,计数为0。
解决步骤
步骤1:调整模型绑定接收字段
推荐用第一种方案更符合开发规范:
方案A:新增专用视图模型(推荐)
不要直接将数据库实体类作为前端提交的接收模型,单独创建用户提交的视图模型:
public class UserCreateViewModel { // 复制原有User实体中需要前端提交的字段,例如: public string username { get; set; } public string email { get; set; } public string phone { get; set; } // 其他原有字段省略 // 新增接收选中技能ID的属性 public List<int> SelectedSkillIds { get; set; } }
方案B:给现有User实体加非映射临时属性
如果不想新建视图模型,可在User类中加非映射属性,避免EF Core将其映射到数据库:
[NotMapped] public List<int> SelectedSkillIds { get; set; } // 同时建议初始化UserSkills避免空引用异常 public IList<UserSkill> UserSkills { get; set; } = new List<UserSkill>();
步骤2:修改前端视图的下拉框绑定
调整select的绑定属性,不需要手动写name属性,asp-for会自动生成正确的绑定名:
<div class="form-group col-md-6"> <label>User Skills</label> <select asp-for="SelectedSkillIds" asp-items="@(new SelectList(ViewBag.Skills,"Value", "Text"))" class="form-control select2" multiple="multiple" data-placeholder="Select a Skills" style="width: 100%;"></select> </div>
步骤3:Post接口中手动构造UserSkill集合
提交后即可拿到选中的技能ID列表,手动组装成UserSkill集合赋值给User实体即可:
[HttpPost] public async Task<IActionResult> adduser(UserCreateViewModel model) { if(ModelState.IsValid) { // 构造User实体 var user = new User { username = model.username, email = model.email, // 其他属性赋值省略 // 手动组装多对多关联数据 UserSkills = model.SelectedSkillIds.Select(skillId => new UserSkill { SkillId = skillId }).ToList() }; // 后续执行用户保存逻辑即可,EF Core会自动处理多对多关联的插入 await _userService.Add(user); return RedirectToAction(nameof(Index)); } // 验证失败时重新加载技能列表返回视图 var skills = await _skillService.GetListByFilter(); ViewBag.Skills = skills.Select(x => new SelectListItem() { Value = x.id.ToString(), Text = x.name }); return View(model); }
如果使用方案B直接接收User实体,直接用user.SelectedSkillIds组装UserSkills集合即可。
内容的提问来源于stack exchange,提问作者ynckaya
相关产品推荐
相关产品推荐

