ASP.NET Core 2.0 Model为表单中未使用的项返回null

问题描述 投票:0回答:2

上下文

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使用?

c# asp.net asp.net-mvc viewmodel
2个回答
2
投票

结果证明这里有两个问题需要解决。

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,一切都很好地绑定,我可以在控制器中看到注释。


1
投票

我不相信有一种方法,在没有它们的情况下传递值。您可以使用隐藏字段来存储要传递回服务器的数据。这是用于为表单中的现有模型字段创建隐藏字段的剃刀语法。

@Html.HiddenFor(x => x.HiddenFieldName)
© www.soinside.com 2019 - 2024. All rights reserved.