Почему параметр метода действия имеет значение null при публикации представления? - PullRequest
0 голосов
/ 20 марта 2019

Это проект ASP.NET MVC. У меня есть представление, которое отображает коллекцию BookRentViewModel предметов.

Когда я нажимаю на кнопку в представлении, представление публикуется в метод действия, называемый rent. У rent метода действия есть параметр с именем 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; }
}       

Проблема в том, что параметр items всегда равен нулю при запуске действия rent.

Есть идеи, почему items равно нулю и не получает коллекцию из вида?

UPDATE Я использовал fiddler, чтобы увидеть, отправлена ​​ли коллекция на сервер, но кажется, что ее невозможно разобрать в элементах BookRentViewModel.

Update3 Вот скриншот из Fiddler с коллекцией, отправленной из представления: enter image description here

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Я пытался воспроизвести исходный код.

Вы можете изменить отображение модели в файле 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" />
}
1 голос
/ 20 марта 2019

Не похоже, что вы устанавливаете значение для public int bookId - в этом случае проверка не будет выполнена, поскольку он не обнуляемый тип.

В любом случае, установите точку останова в методе контроллера ипроверить ошибки на ModelState - см. Получить сообщение об ошибке в случае сбоя ModelState.IsValid?

Редактировать

Включить свойства, но не показать ихна ваш взгляд, используйте вспомогательный тег бритвы: @Html.HiddenFor(x => x.bookId)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...