ViewModel中Letter对象在Post方法中返回Null的问题求助
ViewModel中Letter对象在Post方法中返回Null的问题求助
看起来你遇到了模型绑定的典型问题,导致Post方法里的model.Letter始终为null,进而触发ModelState.IsValid返回false。我来帮你一步步拆解问题并给出解决方案:
1. 模型绑定的Bind属性限制了字段填充
你在Post方法的参数上标注了[Bind("Id,Programs")],但你的ViewModel包含Letter和Programs两个核心属性,这个Bind列表完全没有包含Letter相关的字段,模型绑定器根本不知道要把表单数据填充到model.Letter里。
解决方式:
- 最简单的是直接移除Bind属性,因为你的ViewModel就是专门用来接收请求的,没必要额外限制绑定字段:
public async Task<IActionResult> Create(viewModel model)
- 如果你一定要保留Bind,需要把
Letter加入绑定列表:[Bind("Letter,Programs")]
2. 视图字段的绑定路径要匹配模型结构
你的视图里已经有了Letter.Id的隐藏字段,但要确保绑定路径的写法正确。另外如果后续给Letter添加其他属性,也要统一用asp-for="Letter.XXX"的格式,让绑定器能正确识别字段归属:
<input asp-for="Letter.Id" type="hidden" class="form-control" />
(你原来写的asp-for="@Model.Letter.Id"也能工作,但去掉@Model.更简洁规范)
3. 修正模型设计的不匹配问题
我注意到你的Letter类里,Programs是单个clsPrograms对象,但你在视图里做的是多选复选框列表,这明显逻辑不匹配——多选场景应该对应列表类型。所以需要修改Letter类:
public class Letter{ [Key] public Guid Id { get; set; } // 改为列表类型,匹配多选场景 public List<clsPrograms> Programs { get; set; } }
备注:如果用EF Core持久化,直接保存列表需要配置实体关系;如果只是想保存选中的Program值,也可以改成保存逗号分隔的字符串,具体看你的业务需求。
4. 修复Post方法里的代码错误
你的Post方法有两处明显错误:
_context.Entry(Letter).Property("Programs").CurrentValue = checkboxPrograms;里的Letter变量未定义,应该用model.Letter_context.Add(model);错误,DbContext应该操作Letter实体而非ViewModel,正确写法如下:
try { // 只保留选中的Programs var selectedPrograms = model.Programs.Where(p => p.Selected).ToList(); model.Letter.Programs = selectedPrograms; _context.Add(model.Letter); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } catch (Exception ex) { throw ex; }
做完以上修改后,再测试Post请求,model.Letter应该能被正确填充,ModelState.IsValid也会返回true了。
备注:内容来源于stack exchange,提问作者user788448
相关产品推荐
相关产品推荐

