C# ASP.NET核心-绑定IEnumerable<;T>;到POST上的ViewModel字段

C# ASP.NET核心-绑定IEnumerable<;T>;到POST上的ViewModel字段,c#,razor,asp.net-core,C#,Razor,Asp.net Core,我有一个web应用程序,用于注册参加比赛的团队,每个团队都可以选择一些他们将用于其项目的技术。这些技术保存在标签类中 我正在使用视图模型将表单中的信息绑定到操作。 但是,当我尝试提交表单时,它会占用除技术列表之外的所有其他字段 Label.cs CreateTeamViewModel.cs 公共类CreateTeamViewModel { [必需] 公共字符串TeamName{get;set;} 公共字符串ProjectName{get;set;} 公共字符串ProjectDescription

我有一个web应用程序,用于注册参加比赛的团队,每个团队都可以选择一些他们将用于其项目的技术。这些技术保存在标签类中

我正在使用视图模型将表单中的信息绑定到操作。 但是,当我尝试提交表单时,它会占用除技术列表之外的所有其他字段

Label.cs

CreateTeamViewModel.cs

公共类CreateTeamViewModel
{
[必需]
公共字符串TeamName{get;set;}
公共字符串ProjectName{get;set;}
公共字符串ProjectDescription{get;set;}
[必需]
公共字符串RepositoryLink{get;set;}
公共列表标签=新列表();
}
TeamsController.cs

公共类TeamsController
{
私有只读ApplicationDbContext上下文;
public IActionResult Create()
{
ViewData[“Labels”]=this.context.Labels.ToList();
返回视图();
}
[HttpPost]
公共IActionResult创建(CreateTeamViewModel团队)
{
列表标签=团队标签;
int count=labels.count;//count=0
返回LocalRedirect(“/”);
}
}
Create.cshtml(复选框列表)

@model Competition.Data.ViewModels.CreateTeamViewModel
@{ 
列表标签=视图数据[“标签”]作为列表;
}
@对于(int i=0;i
您需要绑定到视图模型上的
int
列表,而不是
标签的列表。然后,您需要使用所选ID的列表来填充要持久化的
团队
实体上的标签列表:

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>();
}
公共类CreateTeamViewModel
{
[必需]
公共字符串TeamName{get;set;}
公共字符串ProjectName{get;set;}
公共字符串ProjectDescription{get;set;}
[必需]
公共字符串RepositoryLink{get;set;}
公共列表SelectedLabels{get;set;}=new 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>
}
@foreach(标签中的变量标签)
{
@标签。名称
}
请注意,我删除了隐藏的输入。您不应该发布任何用户不能修改的内容,因为即使是隐藏的输入也可能被篡改

发布后,服务器端您将得到一个由用户选择的标签ID列表。只需从数据库中查询相关标签,然后将其分配给正在创建的团队:

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

工作起来很有魅力,尽管我不得不用一个name标记来更改asp for标记。谢谢你的快速回答!
@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>
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();