ASP.NET MVC POST请求无法返回第二个重复变量问题
解决ASP.NET MVC中POST请求无法返回第二个重复类型变量的问题
我之前处理过一模一样的问题!核心原因在于ASP.NET MVC的默认模型绑定器在识别同一类型的多个导航属性时容易出现混淆,另外EF的关联对象加载逻辑也可能导致第二个UnidadeConsumo无法正确返回。下面给你几个实用的解决方案:
解决方案1:使用ViewModel拆分绑定逻辑
直接用实体类作为视图模型时,两个Unidade类型的属性会让模型绑定器分不清表单字段所属的对象。创建一个专门的ViewModel来包装属性,能彻底避免这个问题:
public class InsumoViewModel { public int InsumoId { get; set; } public string Apelido { get; set; } public string Descricao { get; set; } // 明确区分两个Unidade对象 public Unidade Unidade { get; set; } public Unidade UnidadeConsumo { get; set; } }
在视图中使用这个ViewModel时,HtmlHelper会自动生成带有区分前缀的表单字段名(比如Unidade.Apelido和UnidadeConsumo.Apelido),模型绑定器就能准确识别:
@model InsumoViewModel <div class="form-group"> @Html.LabelFor(m => m.Unidade.Apelido, "单位简称") @Html.TextBoxFor(m => m.Unidade.Apelido, new { @class = "form-control" }) </div> <div class="form-group"> @Html.LabelFor(m => m.UnidadeConsumo.Apelido, "消耗单位简称") @Html.TextBoxFor(m => m.UnidadeConsumo.Apelido, new { @class = "form-control" }) </div>
POST Action中直接接收ViewModel,再映射到实体类即可:
[HttpPost] public ActionResult Create(InsumoViewModel viewModel) { if (ModelState.IsValid) { var insumo = new Insumo { Apelido = viewModel.Apelido, Descricao = viewModel.Descricao, UnidadeId = viewModel.Unidade.UnidadeId, Unidade = viewModel.Unidade, UnidadeConsumoId = viewModel.UnidadeConsumo.UnidadeId, UnidadeConsumo = viewModel.UnidadeConsumo }; db.Insumos.Add(insumo); db.SaveChanges(); return RedirectToAction("Index"); } return View(viewModel); }
解决方案2:手动指定绑定前缀(无需ViewModel)
如果不想额外创建ViewModel,可以在Action中手动为两个Unidade对象指定绑定前缀,让模型绑定器能区分它们:
[HttpPost] public ActionResult Create(FormCollection form) { var insumo = new Insumo(); // 绑定Insumo自身的基本属性 TryUpdateModel(insumo, "", new[] { "Apelido", "Descricao", "UnidadeId", "UnidadeConsumoId" }); // 绑定第一个Unidade对象,指定前缀"Unidade" var unidade = new Unidade(); TryUpdateModel(unidade, "Unidade", new[] { "UnidadeId", "Apelido", "Descricao" }); insumo.Unidade = unidade; // 绑定第二个UnidadeConsumo对象,指定前缀"UnidadeConsumo" var unidadeConsumo = new Unidade(); TryUpdateModel(unidadeConsumo, "UnidadeConsumo", new[] { "UnidadeId", "Apelido", "Descricao" }); insumo.UnidadeConsumo = unidadeConsumo; if (ModelState.IsValid) { db.Insumos.Add(insumo); db.SaveChanges(); return RedirectToAction("Index"); } return View(insumo); }
解决方案3:确保EF显式加载关联对象
如果是POST后返回视图时,第二个UnidadeConsumo为null,那大概率是EF的延迟加载没生效,或者没有显式加载这个关联对象。在查询Insumo时,一定要用Include方法同时加载两个导航属性:
public ActionResult Details(int id) { var insumo = db.Insumos .Include(i => i.Unidade) .Include(i => i.UnidadeConsumo) // 必须显式指定加载第二个关联对象 .FirstOrDefault(i => i.InsumoId == id); return View(insumo); }
这样返回视图时,两个Unidade对象都会被正确加载,不会出现空引用的问题。
内容的提问来源于stack exchange,提问作者Sergio Di Fiore
相关产品推荐
相关产品推荐

