我有一个用于注册团队参加比赛的 Web 应用程序,每个团队都可以选择他们将在其项目中使用的多种技术。这些技术保存在 Label 类中。
我正在使用 View 模型将表单中的信息绑定(bind)到操作。 但是,当我尝试提交表单时,它会占用除技术列表之外的所有其他字段。
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>
最佳答案
您需要绑定(bind)到 View 模型上的 int
列表,而不是 Label
列表。然后,您需要使用选定 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>();
}
然后,您需要修改表单以将复选框绑定(bind)到此列表:
@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 <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="86e4e7e2e1e3abc6eae7e4e3eaa8c5e9eae9f4d6e7eae3f2f2e3" rel="noreferrer noopener nofollow">[email protected]</a>">@label.Name</span>
</label>
}
请注意,我删除了隐藏的输入。您不应该发布任何用户无法修改的内容,因为即使隐藏的输入也可能被篡改。
发布后,服务器端最终会得到用户选择的标签 ID 列表。只需从数据库中查询关联标签,然后将其分配给您正在创建的团队即可:
team.Labels = await _context.Set<Label>().Where(x => model.SelectedLabels.Contains(x.Id)).ToListAsync();
关于c# - ASP.NET Core - 将 IEnumerable<T> 绑定(bind)到 POST 上的 ViewModel 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54555548/