asp.net-mvc - ASP.NET Core - 无法跟踪实体类型的实例
问题描述
尝试在编辑操作中更新上下文时遇到问题:
[HttpPost]
public IActionResult Edit(Model.LeaveApplication leaveApplication) {
ViewBag.Title = "Edit Leave Application";
ViewBag.leavePeriodList = context.LeavePeriod.ToList();
ViewBag.LeaveTypeList = context.LeaveType.ToList();
try {
if (ModelState.IsValid) {
if (!validateDateRanges(leaveApplication, "edit")) {
return View(leaveApplication);
}
leaveApplication.NumDays = (float)CalculateNoOfDays(leaveApplication);
context.LeaveApplication.Update(leaveApplication);
context.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DbUpdateException) {
ModelState.AddModelError("", "Unable to edit leave application. " +
"Please try again, and if the problem persists, " +
"please see your system administrator.");
}
return View(leaveApplication);
}
我要做的是检查是否有超过 1 条记录以验证日期范围。如果只有 1 条记录,我将跳过验证并继续更新上下文。但是,我收到一条错误消息:
无法跟踪实体类型“LeaveApplication”的实例,因为已在跟踪具有相同键的此类型的另一个实例。
是什么导致了这个问题?
这是我的构造函数代码:
public class LeaveApplicationController : Controller {
LeaveDBContext context;
private readonly UserManager<ApplicationUser> userManager;
private readonly SignInManager<ApplicationUser> signInManager;
public LeaveApplicationController(LeaveDBContext context, UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager) {
this.context = context;
this.userManager = userManager;
this.signInManager = signInManager;
}
}
解决方案
您永远不应该尝试保存通过帖子创建的对象。出现这种情况有许多安全原因,但您也偶然发现了一个基于 EF 工作方式的实用安全原因。
如果没有更多代码库,很难准确判断,但在某些时候,这个特定LeaveApplication
实例会加载到您的上下文中,然后开始跟踪它。当您尝试保存不同 LeaveApplication
的实例(即已发布的实例)时,EF 无法保存,因为它不跟踪该实例,而是跟踪之前加载的实例。
您应该做的是发布到视图模型类。然后,LeaveApplication
直接从上下文中提取要编辑的实例,并将视图模型中的数据映射到该实例上。最后,保存该实例。然后,您将不再有任何问题,并且您将获得防止过度黑客攻击和其他后期数据篡改的附带好处。此外,您的LeaveApplication
id 应该是 URL 的一部分。永远不要相信发布的 ID。时期。由于 URL 中的 id 唯一标识资源,因此您可以轻松地基于此实现对象级权限。
推荐阅读
- linux - 如何从文件中读取行并根据逗号分隔并分配变量名对其进行拆分
- jquery - 如果图表只有一个,它会占据整个空闲空间
- browser - 将默认浏览器导航到同一选项卡中的新 URL
- pycharm - 更新使用 Flatpak 运行的 PyCharm
- excel - 到今天和其他日期的日期比较
- java - 如何在 RestTemplate (Spring) 中最后执行 ClientHttpRequestInterceptor
- r - 闪亮:主面板中的多个条件面板不起作用
- xcode - 用于 Cordova、Xcode 10 和模拟器的 Visual Studio 工具
- algorithm - 检查两个 3d 网格是否在有效时间内相等
- python - 在没有函数调用的情况下如何启动函数?