简体   繁体   English

ASP.NET Core-绑定IEnumerable <T> 到POST上的ViewModel字段

[英]ASP.NET Core - Bind IEnumerable<T> to a ViewModel field on POST

I have a web application for registering teams to a competition, where each team can select a number of technologies that they will use for their project. 我有一个Web应用程序,用于注册比赛团队,每个团队都可以选择他们将用于项目的多种技术。 The technologies are saved in a Label class. 这些技术保存在Label类中。

I am using a view model to bind the information from the form to the action. 我正在使用视图模型将信息从表单绑定到操作。 However, when I try to submit the form, it takes all other fields, except the list of technologies. 但是,当我尝试提交表单时,它将采用除技术列表以外的所有其他字段。

Label.cs Label.cs

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

    public string Name { get; set; }

    public string ColorPalette { get; set; }
}

CreateTeamViewModel.cs 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 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 (the list of checkboxes) 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>

You need to bind to a list of int instead of a list of Label on your view model. 您需要绑定到int列表而不是视图模型上的Label列表。 Then, you'll need to use that list of selected ids to fill your list of labels on the Team entity you're persisting: 然后,您需要使用所选ID的列表来填充要保留的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>();
}

Then, you'll need to modify your form to bind your checkboxes to this list: 然后,您需要修改表单以将复选框绑定到此列表:

@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>
}

Notice that I removed the hidden inputs. 注意,我删除了隐藏的输入。 You should never post anything that the user should not be able to modify, as even hidden inputs can be tampered with. 永远都不应发布用户无法修改的任何内容,因为即使隐藏的输入也可能被篡改。

After posting, server-side you'll end up with a list of label ids that were selected by the user. 发布后,在服务器端您将获得用户选择的标签ID列表。 Simply query the associated labels out of your database and then assign that to the team you're creating: 只需从数据库中查询关联的标签,然后将其分配给您要创建的团队即可:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM