gpt4 book ai didi

asp.net-mvc - ASP.NET MVC 5 模型绑定(bind)编辑 View

转载 作者:行者123 更新时间:2023-12-04 13:09:29 24 4
gpt4 key购买 nike

对于一个最好用口头和一点代码描述的问题,我无法想出一个解决方案。我正在使用 VS 2013、MVC 5 和 EF6 代码优先;我也在使用 MvcControllerWithContext 脚手架,它生成支持 CRUD 操作的 Controller 和 View 。

简单地说,我有一个包含 CreatedDate 值的简单模型:

public class WarrantyModel
{
[Key]
public int Id { get; set; }
public string Description { get; set; }
DateTime CreatedDate { get; set; }
DateTime LastModifiedDate { get; set; }
}

包含的 MVC 脚手架对其索引、创建、删除、详细信息和编辑 View 使用相同的模型。我想要“创建” View 中的 CreatedDate;我不希望它出现在“编辑” View 中,因为我不希望它的值在编辑 View 发布回服务器时发生变化,并且我不希望任何人能够在表单发布期间篡改该值.

理想情况下,我不希望 CreatedDate 进入编辑 View 。我发现了一些可以放置在模型的 CreatedDate 属性上的属性(例如,[ScaffoldColumn(false)]),这些属性可以防止它出现在编辑 View 中,但是我在回发时遇到绑定(bind)错误,因为 CreatedDate 结束了值为 1/1/0001 12:00:00 AM。这是因为 Edit View 没有将 CreatedDate 字段的值传回 Controller 。

我不想实现需要任何 SQL Server 更改的解决方案,例如在保存 CreatedDate 值的表上添加触发器。如果我想做一个快速修复,我会在显示编辑 View 之前存储 CreatedDate(当然是服务器端),然后在回发时恢复 CreatedDate——这将让我更改 0001 年 1 月 1 日的日期到在呈现 View 之前从数据库中提取的 CreatedDate EF6。这样,我可以将 CreatedDate 作为隐藏表单字段发送,然后在回发后在 Controller 中覆盖其值,但我没有存储服务器端值的好策略(我不想使用 Session 变量或查看包)。

我查看了使用 [Bind(Exclude="CreatedDate")],但这没有帮助。

我的 Controller 的 Edit post-back 函数中的代码如下所示:
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) 对象。上面的 block 并检查 CreatedDate 的 OriginalValue,但是当我尝试访问该值时(如下所示),我得到一个类型为“System.InvalidOperationException”的异常:
var originalCreatedDate = db.Entry(warrantymodel).Property("CreatedDate").OriginalValue;

如果我可以成功检查原始 CreatedDate 值(即数据库中已经存在的值),我可以覆盖 CurrentValue 是什么。但是由于上面这行代码产生了异常,我不知道还能做什么。 (我考虑过在数据库中查询值,但这很愚蠢,因为在呈现编辑 View 之前已经查询了数据库的值)。

我的另一个想法是将 CreatedDate 值的 IsModified 值更改为 false,但是当我调试时,我发现它已经在前面显示的“if” block 中设置为 false:
bool createdDateIsModified = db.Entry(warrantymodel).Property("CreatedDate").IsModified;

我对如何处理这个看似简单的问题一无所知。总之,我不想将模型字段传递给编辑 View ,并且我希望该字段(在此示例中为 CreatedDate)在 View 中的其他编辑字段被回发并使用持久化到数据库时保持其原始值db.SaveChanges()。

任何帮助/想法将不胜感激。

谢谢你。

最佳答案

您应该利用 ViewModel:

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 的意图与域模型的意图有点不同。它为 View 提供了正确渲染所需的足够信息。

ViewModel 还可以保留与您的域完全不相关的信息。它可以包含对表的排序属性或搜索过滤器的引用。将这些放在您的域模型上肯定没有意义!

现在,在您的 Controller 中,您将 ViewModel 中的属性映射到您的域模型并保留您的更改:
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);
}

此外,ViewModel 非常适合合并来自多个模型的数据。如果您有保修的详细 View ,但您还想查看在该保修下完成的所有服务,该怎么办?您可以像这样简单地使用 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; }
}

ViewModel 简单、灵活且非常流行。这是对它们的一个很好的解释: http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

你最终会写很多映射代码。 Automapper很棒,可以完成大部分繁重的工作: http://automapper.codeplex.com/

关于asp.net-mvc - ASP.NET MVC 5 模型绑定(bind)编辑 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21286538/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com