上下文
ASP.NET Core 2.0 MVC项目
问题
使用像这样的视图模型:
public class UpdateReturnIssueViewModel
{
public IssueTrackerIssue Issue { get; set; }
public bool CloseIssue { get; set; }
}
IssueTrackerIssue是这样的:
public class IssueTrackerIssue
{
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[StringLength(19)]
public string OrderNumber { get; set; }
[Range(1, 50)]
public int Quantity { get; set; }
[StringLength(200)]
public string ReturnCustomerComment { get; set; }
}
我为我的View获取数据,如下所示:
[HttpGet]
public IActionResult UpdateReturnIssue(int ID)
{
// populate the view model in some way
return View(this.updateReturnIssueViewModel);
}
在我的视图中,我只使用(即定义输入asp-for标签)IssueTrackerIssue.OrderNumber和CloseIssue。
这样就会发布到控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult UpdateReturnIssue(UpdateReturnIssueViewModel viewModel)
{
if (this.ModelState.IsValid)
{
// Some other processing
}
}
在检查控制器中的viewModel时,我发现除了View中使用的属性外,一切都是null。
题
如何获取从控制器传递到View并返回到Controller的视图模型的完整内容?换句话说,如何完全往返View模型,View模型的某些部分未被View使用?
结果证明这里有两个问题需要解决。
1)由于@JoshMein和其他人友好地指出必须在表单上使用值,否则它们将作为null发回给控制器。使用隐藏值可以克服这个问题。
2)我的视图是主 - 详细信息类型视图和详细信息集合始终返回null,即空集合。我现在意识到这是由于我在View中编写Detail集合的迭代的方式。我在用
@foreach (IssueTrackerIssueComment comment in Model.Issue.Comments)
{
<tr>
<td><input asp-for="@comment.ID" type="hidden" /></td>
<td><input asp-for="@comment.DateCreated" type="hidden" /></td>
<td><input asp-for="@comment.LastUpdated" type="hidden" /></td>
<td>
<input asp-for="@comment.DateCreated" class="form-control" type="date" asp-format="{0:yyyy-MM-dd}" />
</td>
<td>
<input asp-for="@comment.Narrative" class="form-control" />
</td>
<td>
<button asp-action="DeleteReturnIssueComment" [email protected] class="btn btn-primary">
<span class="glyphicon glyphicon-trash" />
</button>
</td>
</tr>
}
ASP.NET显然无法弄清楚这些@comment项目是否绑定到模型,因此它没有将它们传递回Controller。
所以我将Detail Collection从ICollection <>更改为IList <>并使用@for代替@foreach,因此:
@for (int i = 0; i < Model.Issue.Comments.Count; i++)
{
<tr>
<td><input asp-for="@Model.Issue.Comments[i].ID" type="hidden" /></td>
<td><input asp-for="@Model.Issue.Comments[i].DateCreated" type="hidden" /></td>
<td><input asp-for="@Model.Issue.Comments[i].LastUpdated" type="hidden" /></td>
<td>
<input asp-for="@Model.Issue.Comments[i].DateCreated" class="form-control" type="date" asp-format="{0:yyyy-MM-dd}" />
</td>
<td>
<input asp-for="@Model.Issue.Comments[i].Narrative" class="form-control" />
</td>
<td>
<button asp-action="DeleteReturnIssueComment" [email protected][i].ID class="btn btn-primary">
<span class="glyphicon glyphicon-trash" />
</button>
</td>
</tr>
}
既然@Model被用来引用这些项而不是@comment,一切都很好地绑定,我可以在控制器中看到注释。
我不相信有一种方法,在没有它们的情况下传递值。您可以使用隐藏字段来存储要传递回服务器的数据。这是用于为表单中的现有模型字段创建隐藏字段的剃刀语法。
@Html.HiddenFor(x => x.HiddenFieldName)