发布视图时,为什么action方法的参数为null?

时间:2019-03-20 11:13:26

标签: c# asp.net asp.net-mvc

这是一个ASP.NET MVC项目。我有一个视图,显示了BookRentViewModel个项目的集合。

当我单击视图中的按钮时,视图将发布到名为rent的操作方法中。 rent操作方法具有一个称为IEnumerable<BookRentViewModel>类型的项目的参数。

这是视图的代码:

@model IEnumerable<DaramSerl.Models.ViewModels.BookRentViewModel>
@using (Html.BeginForm("rent", "RentBook", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.bookName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.isRented)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.startDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.endDate)
            </th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.EditorFor(modelItem => item.bookName)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.isRented)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.startDate)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.endDate)
                </td>
            </tr>
        }

    </table>

    <input type="submit" value="Create" class="btn btn-primary" />
}

这是操作方法:

[HttpPost]
public async Task<ActionResult> rent(IEnumerable<BookRentViewModel> items)
{
    if (ModelState.IsValid)
    {
        return RedirectToAction("/Index");
    }
    return View();
}

这是BookRentViewModel:

public class BookRentViewModel
{
    [Key]
    public int bookId{ get; set; }
    public string bookName { get; set; }
    public bool isRented { get; set; }
    public DateTime startDate { get; set; }
    public DateTime endDate { get; set; }
}       

问题在于,items动作被触发时,rent参数始终为空。

您知道为什么items为null并且不能从视图中获取集合吗?

更新 我使用提琴手来查看收藏集是否已发布到服务器,但似乎无法将其解析为BookRentViewModel项目。

UPDATE3 这是fiddler的屏幕截图,其中包含从视图发送的集合: enter image description here

2 个答案:

答案 0 :(得分:1)

看起来好像您正在为public int bookId设置一个值-如果那样的话,这将因为其非空类型而无法通过验证。

无论哪种方式,请在控制器方法中设置断点并检查ModelState上的错误-请参见Get error message if ModelState.IsValid fails?

修改

要包括属性但不在视图中显示它们,请使用隐藏字段razor标签帮助器: @Html.HiddenFor(x => x.bookId)

答案 1 :(得分:1)

我尝试复制源代码。

您可以如下更改cshtml文件中的模型映射

@for (int i = 0; i < Model.Count();i++ )
        { 
            <tr>
                <td>@Html.TextBox("items[" + @i + "].bookName", 
                        Model.ElementAt(i).bookName 
                        )</td>
                <td>@Html.CheckBox("items[" + @i + "].isRented",
                        Model.ElementAt(i).isRented
                        )</td>
                <td>@Html.TextBox("items[" + @i + "].startDate",
                        Model.ElementAt(i).startDate
                        )</td>
                <td>@Html.TextBox("items[" + @i + "].endDate",
                        Model.ElementAt(i).endDate
                        )</td>

            </tr>
        }

rent.cshtml文件

@model IEnumerable<WebApplication2.Controllers.BookRentViewModel>
@using (Html.BeginForm("rent", "Rent", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    <table class="table">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.bookName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.isRented)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.startDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.endDate)
            </th>
        </tr>

        @*@foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.EditorFor(modelItem => item.bookName)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.isRented)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.startDate)
                </td>
                <td>
                    @Html.EditorFor(modelItem => item.endDate)
                </td>
            </tr>
        }*@

        @for (int i = 0; i < Model.Count();i++ )
        { 
            <tr>
                <td>@Html.TextBox("items[" + @i + "].bookName", 
                        Model.ElementAt(i).bookName 
                        )</td>
                <td>@Html.CheckBox("items[" + @i + "].isRented",
                        Model.ElementAt(i).isRented
                        )</td>
                <td>@Html.TextBox("items[" + @i + "].startDate",
                        Model.ElementAt(i).startDate
                        )</td>
                <td>@Html.TextBox("items[" + @i + "].endDate",
                        Model.ElementAt(i).endDate
                        )</td>

            </tr>
        }

    </table>

    <input type="submit" value="Create" class="btn btn-primary" />
}