我无法想出一个最好的口头描述和少量代码的问题解决方案。我正在使用 VS 2013、MVC 5 和 EF6 代码优先;我还使用 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 支架对其索引、创建、删除、详细信息和编辑视图使用相同的模型。我want“创建”视图中的 CreatedDate;我do not希望它出现在“编辑”视图中,因为我不希望在编辑视图回发到服务器时更改其值,并且我不希望任何人能够在表单发布期间篡改该值。
理想情况下,我不希望 CreatedDate 进入编辑视图。我找到了一些可以放置在模型的 CreatedDate 属性上的属性(例如,[ScaffoldColumn(false)]),以防止它出现在编辑视图上,但随后我在回发时收到绑定错误,因为 CreatedDate 最终会出现值为 1/1/0001 12:00:00 AM。这是因为“编辑”视图没有将 CreatedDate 字段的值传递回控制器。
我不想实现需要任何 SQL Server 更改的解决方案,例如在保存 CreatedDate 值的表上添加触发器。如果我想做一个快速修复,我会在显示编辑视图之前存储 CreatedDate(当然是服务器端),然后在回发时恢复 CreatedDate - 这将让我更改 1/1/0001 日期到渲染视图之前从数据库中提取的 CreatedDate EF6。这样,我可以将 CreatedDate 作为隐藏表单字段发送,然后在回发后在控制器中覆盖其值,但我没有一个好的策略来存储服务器端值(我不想使用 Session 变量或查看包)。
我查看了使用 [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);
}
我想我也许能够检查 db.Entry(warrantymodel) 对象if
上面的块并检查 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()。
任何帮助/想法将不胜感激。
谢谢。