ASP.NET Ядро 5 — Формы с динамическим количеством полей

#c# #asp.net #asp.net-core #asp.net-core-5.0

#c# #asp.net #asp.net-ядро #asp.net-ядро-5.0

Вопрос:

Я занимаюсь проектом веб-страниц в ASP.NET Ядро 5, и я столкнулся со следующей проблемой. Моя модель выглядит так

   public class Performance
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public string Dates { get; set; }
        public bool DatesRange { get; set; }
        public string Author { get; set; }
        public string Role { get; set; }
        public Venue Venue { get; set; }

    }
 

Теперь, в форме, я хотел бы иметь поля ввода для всех полей модели производительности, кроме Дат. Идея заключается в том, что одно представление может иметь одну или несколько дат, поэтому у пользователя будет возможность добавлять дополнительные строки в форму, столько, сколько необходимо, при создании нового представления.

Что я хотел бы сделать, но не знаю как, так это обработать привязку отправленных данных вручную, чтобы я мог проанализировать все отправленные даты и преобразовать их в одну строку для сохранения в базе данных. Однако я не уверен, как или, скорее, где это сделать, поскольку первое, что срабатывает после нажатия кнопки отправки, — это

         public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Performance.Add(Performance);
            await _context.SaveChangesAsync();

            return RedirectToPage("./Index");
        }
 

и предоставленные данные уже привязаны к модели. Любые поля формы, которые не соответствуют модели, игнорируются. Можете ли вы указать мне правильное направление?

Комментарии:

1. Вы пробовали просто добавлять несколько полей с именем date ? Если вы это сделаете, я полагаю , что model binder свяжет их здесь в виде списка, разделенного запятыми. Итак, если у вас есть, например ?date=2020-12-24amp;date=1820-12-10 , тогда в вашем Dates поле должно быть значение 2020-12-24,1820-12-10 . Тем не менее, учебным решением здесь было бы создать Dates коллекцию, а затем назвать ваши поля в соответствии с соглашениями о сборе .

2. В качестве альтернативы вы всегда можете выполнить некоторую ручную привязку перед вызовом ModelState.IsValid , самостоятельно извлекая значения с помощью Controller.Request свойства, а затем вручную устанавливая их в своей модели. Это быстрый и простой способ обработки исключений одноразовой привязки к модели без внедрения пользовательского связывания модели.

Ответ №1:

Вы могли asp-page-handler бы сделать еще один запрос из внутренней формы ваших страниц razor. Кроме того, вам нужно определить даты, как List<string> Performance будет выглядеть ваша модель

На вашей странице razor вам нужно настроить несколько сообщений

 <form method="post">
<input asp-for="perf.Date" value="Date" />
<button asp-page-handler="Date">Add</button>
<table>
    <th>
        <td>Date</td>
    </th>
    @if (Model.Dates != null)
    {
        for (int i = 0; i < Model.Dates.Count; i  )
        {
            <tr>
                <td>@Model.Dates[i] @Html.HiddenFor(model => Model.Dates[i])</td>
            </tr>
        }
    }
   
    
</table>
<input type="submit" value="Save"/>
 

cshtml.cs файл будет содержать следующие подписи. OnPostDate будет обрабатывать отдельную запись для добавления даты. ‘OnPost’ будет обрабатывать полную публикацию модели.

   [BindProperty] public Performance perf { get; set; }
    [BindProperty] public List<string> Dates { get; set; }
    public void OnGet()
    {
        perf = new Performance();
    }

    public void OnPost()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }
        foreach (string dt in Dates)
        {    
            perf.Date = dt;
            _context.Performance.Add(Performance);
        }
        await _context.SaveChangesAsync();
        return RedirectToPage("./Index");       
    }
    public IActionResult OnPostDate()
    {
        if (Dates.Count == 0)
        {
            Dates = new List<string>();
            Dates.Add(perf.Date);
        }
        else
        {
            Dates.Add(perf.Date);
        }

        
        return Page();
    }
 

Вывод:

введите описание изображения здесь