Передача IEnumerable<Entity> из представления в контроллер в ASP.NET Core 8 MVC

Это мой взгляд:

@model IEnumerable<HourlyLimit>
<html>
    <head><title></title></head>
    <body>
        <form method = "post" action = "~/Admin/HourlyLimits/Set" enctype = "multipart/form-data">
            @foreach (var item in Model)
            {
                <input asp-for = "@item.ID" hidden />
                <input asp-for = "@item.Date" hidden />
                <input asp-for = "@item.Hour" hidden />
                <input asp-for = "@item.Capacity" type = "number">
            }
            <button type = "submit"></button>
    </body>
</html>

В методе Get этого действия я передаю IEnumerable<HourlyLimit> представлению следующим образом:

IEnumerable<HourlyLimit> hourlyLimits = await _db.HourlyLimits
                                                 .OrderBy(h => h.Hour)
                                                 .ToListAsync();

return View(hourlyLimits);

Когда страница загружается, теги <input /> корректно заполняются из существующих записей в базе данных; так что кажется, что привязка модели работает нормально.

Проблема в том, что когда я отправляю форму, объект, который передается методу Post этого действия, имеет count, равный 0:

[HttpPost]
// hourlyLimits.Count is 0 here when I hit the breakpoint 
public async Task<IActionResult> Set(IEnumerable<HourlyLimit> hourlyLimits) 
{
    if (!ModelState.IsValid)
    {
        //...
    }

    try
    {
        //...
    }
    catch (Exception)
    {
        //...
    }
}

В чем дело? Как я могу отправить IEnumerable<HouryLimit> из представления?

Почему вы используете enctype = "multipart/form-data"?

Progman 20.05.2024 12:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы подготовить контекст для корректной работы привязки MVC, используйте индексацию, как показано ниже:

@{ int i=0; }
@foreach (var item in Model)
{
  <input type = "hidden" asp-for = "@item.ID" name = "@("hourlyLimits["+i+"].ID")" />
  <input type = "hidden" asp-for = "@item.Date" name = "@("hourlyLimits["+i+"].Date")"  />
  <input type = "hidden" asp-for = "@item.Hour" name = "@("hourlyLimits["+i+"].Hour")"  />
  <input type = "number" asp-for = "@item.Capacity" name = "@("hourlyLimits["+i+"].Capacity")" /> 
  @(i++)
}

Второй вариант — объявить модель данных представления как IList<HourlyLimit> и использовать оператор for:

@model IList<HourlyLimit>
<html>
    <head><title></title></head>
    <body>
        <form method = "post" action = "~/Admin/HourlyLimits/Set" >
             @for (int i = 0; i < Model.Count(); i++)
            {
  <input type = "hidden" asp-for = "@Model[i].ID" name = "@("hourlyLimits["+i+"].ID")" />
  <input type = "hidden" asp-for = "@Model[i].Date" name = "@("hourlyLimits["+i+"].Date")"  />
  <input type = "hidden" asp-for = "@Model[i].Hour" name = "@("hourlyLimits["+i+"].Hour")"  />
  <input type = "number" asp-for = "@Model[i].Capacity" name = "@("hourlyLimits["+i+"].Capacity")" /> 
            }
            <button type = "submit"></button>
    </body>
</html>

Попробовал первый вариант, работает отлично. Спасибо! Вы также знаете, как я могу поставить <span> для подтверждения Capacity? В типичной ситуации я бы просто добавил asp-validation-for = "Capacity", но не знаю, как это сделать в данном случае.

Sina Abbaszadeh 20.05.2024 15:07

@SinaAbbaszadeh: Хороший вопрос. data-valmsg-for должен быть создан с использованием того же правила: "@("hourlyLimits["+i+"].Capacity")". Щелкните правой кнопкой мыши на отображаемой странице и выберите «Просмотреть исходный код страницы», чтобы проверить сгенерированный HTML-код, связанный с тегами <input> и <span>.

Jackdaw 20.05.2024 17:19

Другие вопросы по теме