我已经多次遇到此问题。我以不同的方式解决了这个问题,但总觉得有更好的方法来处理这种情况。寻找解决方案(最佳实践)已经取得了胜利。希望得到一些圣人的建议。MVC传递模型返回控制器,预填充数据
这种情况是这样的:我正在构建一个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。大部分其他值已经由管理员用户设置。所以我通过用户验收测试对象,以我的观点,看起来像这样:
@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" />
}
我controllerAction看起来是这样的:
[HttpPost]
public ActionResult UatEvalution(Uat uat)
{
//process data
//Update(uat);
//SaveChanges();
}
的问题是,在控制器我UAT对象只具有的TestCases数据。其他所有内容都为null或0. Uat中的TestCases只有注释和状态的数据,其他的都是null或0.因此,如果我尝试在此模型上运行更新,则会出现以下错误:具有相同密钥的对象已经存在于ObjectStateManager中。我研究过这个,这对我很有意义。但要解决这个问题,我已经做了在过去的两两件事之一:
我在视图中创建一批隐藏字段来填充模型属性的其余部分,这样,当模型传回给Controller,所有的数据都以我从数据库中取出时的相同方式填充;除了它有用户所做的更改。
我重新从数据库中拉出TestCase条目,对该条目进行适当的修改,然后对SaveChanges()进行相应的修改。
这两种解决方案对我来说都很难看,而且我确信我做的不正确。虽然这在过去为我解决了这个问题,但这会导致我的视图混淆隐藏的字段,或者最终向db提出太多请求。我的应用程序很小,因此这些解决方法现在没有太大影响,但我确实想要养成最佳做法的习惯。任何帮助将不胜感激,因为它始终来自SO社区。提前致谢!
谢谢您对von的解释。 ViewModels在过去帮助过我。有时候我觉得我不得不破解一些东西,但实际上我猜这只是mvc的工作原理。感谢您的反馈! – nycfdtd
不客气。我希望你选择在当前的项目@nycfdtd中也有viewmodels。 –