ASP.NET Core - привязать IEnumerable <T>к полю ViewModel на POST - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть веб-приложение для регистрации команд на соревнование, где каждая команда может выбрать ряд технологий, которые они будут использовать для своего проекта.Технологии сохраняются в классе Label.

Я использую модель представления, чтобы связать информацию из формы с действием.Однако, когда я пытаюсь отправить форму, она занимает все остальные поля, кроме списка технологий.

Label.cs

public class Label
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public string ColorPalette { get; set; }
}

CreateTeamViewModel.cs

public class CreateTeamViewModel
{
    [Required]
    public string TeamName { get; set; }

    public string ProjectName { get; set; }

    public string ProjectDescription { get; set; }

    [Required]
    public string RepositoryLink { get; set; }

    public List<Label> Labels = new List<Label>();
}

TeamsController.cs

public class TeamsController
{
    private readonly ApplicationDbContext context;

    public IActionResult Create()
    {
        ViewData["Labels"] = this.context.Labels.ToList();
        return View();
    }

    [HttpPost]
    public IActionResult Create(CreateTeamViewModel team)
    {
        List<Label> labels = team.Labels;
        int count = labels.Count; // count = 0
        return LocalRedirect("/");
    }
}

Create.cshtml (список флажков)

@model Competition.Data.ViewModels.CreateTeamViewModel

@{ 
    List<Label> labels = ViewData["Labels"] as List<Label>;
}

<form asp-action="Create">
    <div class="form-check">
        @for(int i = 0; i < labels.Count; i++)
        {
            <input asp-for="@Model.Labels[i].IsSelected" type="checkbox" />
            <label asp-for="@Model.Labels[i].Name">
                <span class="badge badge-@labels[i].ColorPalette">@labels[i].Name</span>
            </label>
            <input asp-for="@Model.Labels[i].Name" type="hidden" value="@labels[i].Name" />
            <input asp-for="@Model.Labels[i].ColorPalette" type="hidden" value="@labels[i].ColorPalette" />
        }
    </div>
    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-default" />
    </div>
</form>

1 Ответ

0 голосов
/ 06 февраля 2019

Вам необходимо привязать список int вместо списка Label в модели представления.Затем вам нужно будет использовать этот список выбранных идентификаторов, чтобы заполнить список ярлыков для сущности Team, которую вы сохраняете:

public class CreateTeamViewModel
{
    [Required]
    public string TeamName { get; set; }

    public string ProjectName { get; set; }

    public string ProjectDescription { get; set; }

    [Required]
    public string RepositoryLink { get; set; }

    public List<int> SelectedLabels { get; set; } = new List<int>();
}

Затем вам нужно изменить свою форму напривяжите свои флажки к этому списку:

@foreach (var label in labels)
{
    <input asp-for="SelectedLabels" id="Label@(label.Id)" value="@label.Id" type="checkbox" />
    <label id="Label@(label.Id)">
        <span class="badge badge-@label.ColorPalette">@label.Name</span>
    </label>
}

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

После публикации на стороне сервера вы получите списокидентификаторов меток, которые были выбраны пользователем.Просто запросите соответствующие метки из вашей базы данных, а затем назначьте их команде, которую вы создаете:

team.Labels = await _context.Set<Label>().Where(x => model.SelectedLabels.Contains(x.Id)).ToListAsync();
...