对于一个最好的口头描述和少量代码的问题,我无法提出解决方案。我先使用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支架对其索引,创建,删除,详细信息和编辑视图使用相同的模型。我想在“创建”视图中创建日期;我不希望在“编辑”视图中使用它,因为我不希望在将编辑视图发布回服务器时更改其值,并且我不希望任何人能够在表单发布期间篡改该值。
理想情况下,我不希望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变量或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)对象,并在OriginalValue中检查CreatedDate,但是当我尝试访问该值时(如下所示),我得到了'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()。
任何帮助/想法将不胜感激。
谢谢。
您应该利用ViewModels:
public class WarrantyModelCreateViewModel
{
public int Id { get; set; }
public string Description { get; set; }
DateTime CreatedDate { get; set; }
DateTime LastModifiedDate { get; set; }
}
public class WarrantyModelEditViewModel
{
public int Id { get; set; }
public string Description { get; set; }
DateTime LastModifiedDate { get; set; }
}
ViewModel的意图与域模型的意图有所不同。它为视图提供了正确渲染所需的足够信息。
ViewModels还可以保留与您的域完全无关的信息。它可以包含对表或搜索过滤器上的sorting属性的引用。那些当然不适合放在您的域模型中!
现在,在控制器中,将属性从ViewModels映射到域模型,并保留您的更改:
public ActionResult Edit(WarrantyModelEditViewModel vm)
{
if (ModelState.IsValid)
{
var warrant = db.Warranties.Find(vm.Id);
warrant.Description = vm.Description;
warrant.LastModifiedDate = vm.LastModifiedDate;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(warrantymodel);
}
此外,ViewModels非常适合合并来自多个模型的数据。如果您有详细的保修视图,但又想查看该保修下的所有服务怎么办?您可以像这样简单地使用ViewModel:
public class WarrantyModelDetailsViewModel
{
public int Id { get; set; }
public string Description { get; set; }
DateTime CreatedDate { get; set; }
DateTime LastModifiedDate { get; set; }
List<Services> Services { get; set; }
}
ViewModels简单,灵活并且非常流行。这是对它们的很好的移植:http : //lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
您将最终编写很多映射代码。Automapper
很棒,可以完成大部分繁重的工作:http : //automapper.codeplex.com/
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句