我无法想出一个最好用口头和一点代码描述的问题的解决方案。我正在使用VS 2013、MVC 5和EF6 Code-First;我还使用了MvcControllerWithContext脚手架,它生成支持CRUD操作的控制器和视图。
简单地说,我有一个包含CreatedDate值的简单模型:
public class WarrantyModel
{
[Key]
public int Id { get; set; }
public string Description { get; set; }
DateTime CreatedDate { get; set; }
DateTime LastModifiedDate { get; set; }
}
包含MVC脚手架使用相同的模型用于其索引、创建、删除、详细信息和编辑视图。我希望在“创建”视图中包含“CreatedDate”,但是我不想在“编辑”视图中包含它,因为当编辑视图被提交到服务器时,我不希望它的值发生变化,也不希望任何人在表单提交期间篡改该值。
理想情况下,我不希望“CreatedDate”出现在编辑视图中。我发现可以在模型的“CreatedDate”属性上放置一些属性(例如[ScaffoldColumn(false)]),以防止它出现在编辑视图中,但是在回发时我会遇到绑定错误,因为“CreatedDate”的值最终会变成1/1/0001 12:00:00 AM。这是因为编辑视图没有将“CreatedDate”字段的值传回控制器。
我不想实现需要进行任何SQL Server更改的解决方案,例如在保存“CreatedDate”值的表上添加触发器。如果我想快速修复,我会在呈现编辑视图之前存储“CreatedDate”(当然是在服务器端),然后在回发时还原“CreatedDate”--这样我就可以将“CreatedDate”作为隐藏表单字段发送,并在回发后在控制器中覆盖其值,但是我没有一个好的策略来存储服务器端的值(我不想使用Session变量或ViewBag)。
我考虑过使用[Bind(Exclude="CreatedDate")],但这并没有帮助。
我的控制器编辑回发函数中的代码如下:
public ActionResult Edit([Bind(Include="Id,Description,CreatedDate,LastModifiedDate")] WarrantyModel warrantymodel)
{
if (ModelState.IsValid)
{
db.Entry(warrantymodel).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(warrantymodel);
}
我想我可能能够在上面的if
块中检查db.Entry(warrantymodel)对象,并查看CreatedDate的OriginalValue,但是当我尝试访问该值(如下所示)时,我会收到'System.InvalidOperationException'类型的异常:
var originalCreatedDate = db.Entry(warrantymodel).Property("CreatedDate").OriginalValue;
如果我能够成功地检查原始的CreatedDate值(即已经在数据库中的值),那么我就可以覆盖掉CurrentValue的值。但是由于上面这行代码会生成一个异常,所以我不知道还有什么其他办法。(我考虑过查询数据库来获取该值,但这很愚蠢,因为在渲染编辑视图之前数据库已经查询了该值)。
另一个我想到的办法是将CreatedDate值的IsModified值更改为false,但是当我进行调试时,我发现它已经在我的前面显示的'if'块中被设置为false了。
bool createdDateIsModified = db.Entry(warrantymodel).Property("CreatedDate").IsModified;
我对如何处理这个看似简单的问题已经无计可施了。总之,我不想将模型字段传递给编辑视图,并且我希望该字段(例如CreatedDate)在其他编辑视图字段被提交并使用db.SaveChanges()持久化到数据库时,仍保持原始值。
非常感谢任何帮助/想法。
谢谢。
public ActionResult Edit([Bind(Include="Id,Description,CreatedDate,LastModifiedDate")] WarrantyModel warrantymodel)
您的 db.Warranties.Find(vm.Id) 和映射是否执行相同的操作? - Jazimov