ASP.NET MVC 5主从表记录保存失败问题求助
解决EF5中主从表无法保存的问题
以下是针对你代码中问题的排查和修复方案:
1. 修复前后端参数大小写不匹配问题
C#模型属性采用PascalCase命名(如TestType),但前端JS传递的是camelCase命名(如testType),默认ModelBinder无法正确映射,导致Deta数组属性为空,触发错误分支。
修改前端JS构造数据的代码:
//Collect Multiple Order List For Pass To Controller $("#saveDeta").click(function (e) { e.preventDefault(); var detaArr = []; detaArr.length = 0; $.each($("#detailsTable tbody tr"), function () { detaArr.push({ // 修改为PascalCase,匹配后端模型属性 TestType: $(this).find('td:eq(0)').html(), TestDate: $(this).find('td:eq(1)').html(), Driver: $(this).find('td:eq(2)').html(), Place: $(this).find('td:eq(3)').html() }); }); var data = JSON.stringify({ missionCode: $("#missionCode").val(), startDate: $("#startDate").val(), endDate: $("#endDate").val(), deta: detaArr }); $.when(saveDeta(data)).then(function (response) { console.log(response); }).fail(function (err) { console.log(err); }); });
2. 解决DateTime参数绑定失败问题
前端日期输入格式不符合ASP.NET MVC默认解析规则,导致startDate、endDate等参数绑定失败。
视图层修改:
将日期输入框改为标准HTML5日期类型,确保输出格式兼容后端:
<!-- 修改Start Date输入框 --> <div class="col-md-4"> <input type="date" id="startDate" name="startDate" placeholder="Start Date" class="form-control" /> </div> <!-- 修改End Date输入框 --> <div class="col-md-4"> <input type="date" id="endDate" name="endDate" placeholder="End Date" class="form-control" /> </div> <!-- 修改Test Date输入框 --> <div class="col-md-4"> <input type="datetime-local" id="testDate" name="testDate" placeholder="Test Date" class="form-control" /> </div>
后端控制器修改:
将DateTime参数改为可空类型,避免格式问题直接导致参数绑定失败,并增强判断逻辑:
public ActionResult SaveDeta(string missionCode, DateTime? startDate, DateTime? endDate, Deta[] deta) { string result = "Error! Test Detail Is Not Complete!"; // 增强非空与有效性判断 if (!string.IsNullOrEmpty(missionCode) && startDate.HasValue && endDate.HasValue && deta != null && deta.Length > 0) { var tstId = Guid.NewGuid(); Test model = new Test { TestID = tstId, MissionCode = missionCode, StartDate = startDate.Value, EndDate = endDate.Value }; db.Tests.Add(model); foreach (var item in deta) { // 跳过TestDate为空的无效记录 if (!item.TestDate.HasValue) continue; var id = Guid.NewGuid(); Deta O = new Deta { DetaId = id, TestType = item.TestType, TestDate = item.TestDate.Value, Driver = item.Driver, Place = item.Place, TestID = tstId }; db.Detas.Add(O); } try { db.SaveChanges(); result = "Success! Test with Detail Is Complete!"; } catch (Exception ex) { // 返回具体错误信息便于排查 result = $"Error: {ex.Message}"; } } return Json(result, JsonRequestBehavior.AllowGet); }
3. 验证EF模型导航属性配置
确保Test和Deta模型的导航属性正确配置,让EF识别主从关系:
// Test模型 public class Test { public Guid TestID { get; set; } public string MissionCode { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } // 主表到从表的导航属性 public virtual ICollection<Deta> Detas { get; set; } } // Deta模型 public class Deta { public Guid DetaId { get; set; } public string TestType { get; set; } public DateTime TestDate { get; set; } public string Driver { get; set; } public string Place { get; set; } public Guid TestID { get; set; } // 从表到主表的导航属性 public virtual Test Test { get; set; } }
4. 可选优化:使用ViewModel统一接收参数
创建ViewModel封装所有提交数据,提升代码可读性和绑定可靠性:
public class TestWithDetaViewModel { public string MissionCode { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public List<Deta> DetaList { get; set; } }
修改控制器方法:
public ActionResult SaveDeta(TestWithDetaViewModel model) { string result = "Error! Test Detail Is Not Complete!"; if (model != null && !string.IsNullOrEmpty(model.MissionCode) && model.DetaList != null && model.DetaList.Count > 0) { var tstId = Guid.NewGuid(); Test test = new Test { TestID = tstId, MissionCode = model.MissionCode, StartDate = model.StartDate, EndDate = model.EndDate }; db.Tests.Add(test); foreach (var item in model.DetaList) { if (!item.TestDate.HasValue) continue; var id = Guid.NewGuid(); Deta deta = new Deta { DetaId = id, TestType = item.TestType, TestDate = item.TestDate.Value, Driver = item.Driver, Place = item.Place, TestID = tstId }; db.Detas.Add(deta); } try { db.SaveChanges(); result = "Success! Test with Detail Is Complete!"; } catch (Exception ex) { result = $"Error: {ex.Message}"; } } return Json(result, JsonRequestBehavior.AllowGet); }
对应修改前端JS的data构造:
var data = JSON.stringify({ missionCode: $("#missionCode").val(), startDate: $("#startDate").val(), endDate: $("#endDate").val(), detaList: detaArr });
内容的提问来源于stack exchange,提问作者Ahmed Mulugeta
相关产品推荐
相关产品推荐

