[英]Why does my List of Objects rendered as Checkboxes return an Empty List? [ASP.NET Core - 3.1]
I'm trying to render a List<PlayerCheckbox>
as Checkboxes.我正在尝试将List<PlayerCheckbox>
呈现为复选框。
PlayerCheckbox looks like this: (added empty constructor as per @jcwmoore 's answer, sadly nothing changed with this addition alone) PlayerCheckbox 看起来像这样:(根据@jcwmoore 的回答添加了空构造函数,遗憾的是,仅此添加没有任何改变)
public class PlayerCheckbox
{
public PlayerCheckbox(string discordName, ulong discordId, bool selected = false)
{
DiscordName = discordName;
DiscordId = discordId;
Selected = selected;
}
public PlayerCheckbox()
{
}
public string DiscordName { get; set; }
public ulong DiscordId { get; set; }
public bool Selected { get; set; }
}
The CreateBingoTaskModel looks like this: (ViewModel I am working with on the Create page, added a default constructor here aswell per @jcwmoore 's input, just in case) CreateBingoTaskModel 看起来像这样:(我在创建页面上使用的 ViewModel,在此处添加了一个默认构造函数以及每个 @jcwmoore 的输入,以防万一)
public class CreateBingoTaskModel
{
public CreateBingoTaskModel()
{
}
/// <summary>
/// Discord Id of the creator of this BingoTask
/// </summary>
public BingoPlayer Creator { get; set; }
[Range(0, 100)]
public int Difficulty { get; set; }
/// <summary>
/// List of IDs that are not allowed to receive this bingo task
/// </summary>
public List<BingoPlayer> BlackListIds { get; set; } = new List<BingoPlayer>();
/// <summary>
/// Title of this bingo task
/// </summary>
[Required]
public string BingoTitle { get; set; }
/// <summary>
/// Description of this bingo task
/// </summary>
[Required]
public string BingoDescription { get; set; }
public DateTime RaffledOn { get; set; }
public List<PlayerCheckbox> BlackList;
}
The setup GET-Create looks like this:设置 GET-Create 如下所示:
public async Task<IActionResult> Create()
{
CreateBingoTaskModel createBingoModel = new CreateBingoTaskModel();
createBingoModel.BlackList = new List<PlayerCheckbox>();
var user = await appDb.BingoPlayers.SingleOrDefaultAsync(player =>
player.LoginName == HttpContext.Session.GetString("user"));
foreach (BingoPlayer bp in appDb.BingoPlayers)
{
PlayerCheckbox playerCheckbox =
new PlayerCheckbox(bp.Name, bp.DiscordId);
if (playerCheckbox.DiscordId != user.DiscordId)
{
createBingoModel.BlackList.Add(playerCheckbox);
}
}
return View(createBingoModel);
}
The POST-Create looks like this: POST-Create 如下所示:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(CreateBingoTaskModel createBingoTaskModel)
{
if (ModelState.IsValid)
{
var user = await appDb.BingoPlayers.SingleOrDefaultAsync(player =>
player.LoginName == HttpContext.Session.GetString("user"));
foreach (PlayerCheckbox checkbox in createBingoTaskModel.BlackList)
{
if (checkbox.Selected)
{
var player = appDb.BingoPlayers.Single(bingoPlayer => bingoPlayer.DiscordId == checkbox.DiscordId);
createBingoTaskModel.BlackListIds.Add(player);
}
}
createBingoTaskModel.BlackListIds.Add(user);
BingoTask newBingoTask = new BingoTask
{
Difficulty = createBingoTaskModel.Difficulty,
BingoTitle = createBingoTaskModel.BingoTitle,
BingoDescription = createBingoTaskModel.BingoDescription,
BlackListIds = createBingoTaskModel.BlackListIds
};
appDb.Add(newBingoTask);
await appDb.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(createBingoTaskModel);
}
Looking at the Model in the POST-Create Header:查看 POST-Create Header 中的 Model: shows that the BlackList is now null .显示黑名单现在是 null 。
I Do not understand why this is null, I was expecting all of the players except for the current logged in user, even if the logic was incorrect,
.BlackList
should at least be initialized.我不明白为什么这是null,我期待除了当前登录用户之外的所有玩家,即使逻辑不正确,至少应该初始化.BlackList
。
The Checkbox List Code I am using looks like this:我使用的复选框列表代码如下所示:
@using App.API.Models
@model App.API.Models.CreateBingoTaskModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>BingoTask</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Difficulty" class="control-label"></label>
<input asp-for="Difficulty" class="form-control" />
<span asp-validation-for="Difficulty" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BingoTitle" class="control-label"></label>
<input asp-for="BingoTitle" class="form-control" />
<span asp-validation-for="BingoTitle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="BingoDescription" class="control-label"></label>
<input asp-for="BingoDescription" class="form-control" />
<span asp-validation-for="BingoDescription" class="text-danger"></span>
</div>
<div class="form-group">
<span>BlackList</span>
@for (int i = 0; i < Model.BlackList.Count; i++)
{
<input hidden asp-for="BlackList[i].DiscordId" />
<input hidden asp-for="BlackList[i].DiscordName" />
<input asp-for="BlackList[i].Selected" type="checkbox" />
@Model.BlackList[i].DiscordName
<br />
}
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
and is taken from this answer here: https://forums.asp.net/t/2164304.aspx?Asp+net+MVC+Core+giving+null+checkbox+data+instead+of+all+selected+checkboxes+on+HTTPPost并取自这里的答案: https://forums.asp.net/t/2164304.aspx?Asp+net+MVC+Core+giving+null+checkbox+data+instead+of+all+selected+checkboxes+开启+HTTPPost
Many implementations of CheckboxLists have extremely similar frontend code with the only major change being a replacement of for with foreach(playerCheckbox in BlackList) which I have tried too. CheckboxLists 的许多实现都有非常相似的前端代码,唯一的主要变化是用我也尝试过的 foreach(playerCheckbox in BlackList) 替换 for。
My FormData looks... fine?我的 FormData 看起来……还好吗? (Except the extra values at the bottom) (底部的额外值除外)
I do NOT understand at all why the binding doesn't work here.我完全不明白为什么绑定在这里不起作用。 Am I so tired that I am overlooking somethingy extremely simple?我是不是太累了,以至于忽略了一些非常简单的事情?
If more information / code is needed, I will gladly provide more context where needed.如果需要更多信息/代码,我很乐意在需要时提供更多上下文。
To my knowledge, the model binder requires a default (parameterless) constructor in the model class.据我所知,model binder 需要 model class 中的默认(无参数)构造函数。 The model class is fine, but the PlayerCheckbox does not have a parameterless constructor. model class 没问题,但 PlayerCheckbox 没有无参数构造函数。 Try either removing your constructor, or adding a parameterless one, to the PlayerCheckbox class.尝试删除您的构造函数,或添加一个无参数的构造函数到 PlayerCheckbox class。
public class PlayerCheckbox
{
// default parameterless constructor to support deserialization
public PlayerCheckbox()
{
}
public PlayerCheckbox(string discordName, ulong discordId, bool selected = false)
{
DiscordName = discordName;
DiscordId = discordId;
Selected = selected;
}
public string DiscordName { get; set; }
public ulong DiscordId { get; set; }
public bool Selected { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.