【问题标题】:Why parameter of the action method is null when view is posted?为什么发布视图时action方法的参数为null?
【发布时间】:2019-08-11 01:38:16
【问题描述】:

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

当我单击视图中的按钮时,视图将发布到一个名为rent 的操作方法。 rent action 方法有一个名为 items 类型的参数 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; }
}       

问题是当rent动作被触发时,items参数总是为空。

知道为什么items 为空并且没有从视图中获取集合吗?

更新 我使用 fiddler 查看集合是否已发布到服务器,但似乎无法将其解析为 BookRentViewModel 项。

更新3 这是 fiddler 的屏幕截图,其中包含从视图发送的集合:

【问题讨论】:

  • 为什么要提交所有数据?表单做什么
  • 来自 fiddler 的更新数据看起来不错,但如果您发布原始请求正文会更容易发现问题 - 您可以从开发工具中的浏览器网络选项卡中获取。
  • 我打赌这是你的问题。 stackoverflow.com/a/17037925/7840778
  • @SteveLand 感谢它的工作!!!

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


【解决方案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" />
}

【讨论】:

    【解决方案2】:

    您似乎没有为 public int bookId 设置值 - 如果是这种情况,则验证失败,因为它是不可为空的类型。

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

    编辑

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

    【讨论】:

    • 好的,那么请将请求正文添加到您的问题中。
    猜你喜欢
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    相关资源
    最近更新 更多