我现在已经多次遇到这个问题。我以不同的方式解决了这个问题,但总觉得有更好的方法来处理这种情况。寻找解决方案(最佳实践)已经取得了成果。希望得到一些圣人的建议。
场景是这样的:我正在构建一个 MVC4 Web 应用程序。我正在将一个复杂的模型传递给我的视图。例如:
public class Uat
{
public int UatId { get; set; }
public int ProjectId { get; set; }
public virtual Project Project { get; set; }
public virtual ICollection<TestCase> TestCases { get; set; }
public UatStatus Status { get; set; }
public string StartDate { get; set; }
public string StatusChangeDate { get; set; }
public string ProductVersion { get; set; }
public string Introduction { get; set; }
public bool isActive { get; set; }
}
我想将此模型传递给视图并让用户仅更新模型的某些部分。在我正在处理的当前实例中,用户正在更新子对象(TestCase)的两个字段。TestCase 对象如下所示:
public class TestCase
{
[Key]
public int TestCaseId { get; set; }
public int UatId { get; set; }
public virtual Uat Uat { get; set; }
public virtual ICollection<Step> Steps { get; set; }
public TestCaseStatus Status { get; set; }
public string Title { get; set; }
public string Comment { get; set; }
}
用户只编辑TestCase.Comment 和TestCase.Status。大多数其他值已由管理员用户设置。所以我将一个 Uat 对象传递给我的视图,如下所示:
@Model ClientPortal.Models.Uat
@{
ViewBag.Title = "Uat";
}
<h2>Uat</h2>
@using (Html.BeginForm("UatEvalution", "Client"))
{
@Html.ValidationSummary(true)
<div>
@{var iteration = 0;}
@foreach (var testCase in Model.TestCases)
{
<div class="well">
<span class="testCaseTitle"><h4>@testCase.Title</h4></span>
<br />
<br />
<ol style="margin-left:40px">
@foreach (var step in testCase.Steps)
{
<li>@step.Description</li>
}
</ol>
<br />
<input type="checkbox" name="TestCases[@iteration].Status" value="2" />Approve
<input type="checkbox" name="TestCases[@iteration].Status" value="1" />Deny
<br />
<span><textarea name="TestCases[@iteration].Comment"></textarea></span>
@{iteration = iteration + 1;
}
</div>
}
</div>
<input type="submit" />
}
我的控制器动作看起来像这样:
[HttpPost]
public ActionResult UatEvalution(Uat uat)
{
//process data
//Update(uat);
//SaveChanges();
}
问题是,我在控制器中的 uat 对象只有 TestCases 数据。其他所有内容为 null 或 0。Uat 中的 TestCases 仅包含 Comment 和 Status 的数据,其他所有内容均为 null 或 0。因此,如果我尝试在此模型上运行 Update,我会收到错误消息:具有相同键的对象ObjectStateManager 中已经存在。我已经研究过了,这对我来说很有意义。但是为了解决这个问题,我过去做了两件事之一:
我在视图中创建了一堆隐藏字段来填充模型中的其余属性,这样当模型传回控制器时,所有数据的填写方式与我从D b; 除了它具有用户所做的更改。
我从数据库中重新提取 TestCase 条目,对该条目进行适当的更改,然后 SaveChanges()。
这两种解决方案对我来说都很难看,而且我确信我做错了什么。虽然这在过去为我解决了这个问题,但它会导致我的视图被隐藏字段弄得杂乱无章,或者我最终向数据库发出了太多请求。我的应用程序很小,所以这些变通办法现在没有太大的效果,但我真的很想养成最佳实践的习惯。任何帮助将不胜感激,因为它总是来自 SO 社区。提前致谢!