.NET Core 提交将除 id 外的所有数据传递给控制器

.NET Core submit passes all the data to the controller except for the id

.NET Core 3.1 与 EF Core,试图更新加载到表单中的数据,但由于某种原因,它在提交时设置了 Id = 0,我不知道为什么。或者,如果我显式设置 id 值,则控制器会为所有记录获取空值。重要的是,它是我发送到数据库的实体列表。

我可以使用相同的表单创建多条记录。但是,如果我用现有记录加载表单,并想进行更改,我就做不到。如果我不为每条记录输入 Id,每条记录的 Id 将设置为零。如果我确实输入了每条记录的 Id,表单似乎可以正确提交,因为我正在查看 Chrome DevTools 并看到值在那里,包括 Id,但随后控制器获取了该数据,并且它是空的...

ETA 当我提交每行都包含 Id 的表单时,问题似乎是第 41 行引起的。我不知道这是否意味着 41 行太多,或者数据本身存在一些问题,这意味着控制器不会拾取任何数据......但这两者都没有意义,因为表单加载 62 行就好了。

这是它的简化版本,其中包含关键部分,因此很有意义。

我的模特:

@model List<EvaluationsModel>

我的表格:

@{
    var createOrUpdate = "Update";
    if (Model[0].IsCreate)
    {
       createOrUpdate = "Create";
    }
}       

<form id="evalForm" asp-action="@createOrUpdate">

@for (var i = 0; i < Model.Count; i++)
{
    <textarea asp-for="@Model[i].Comments" rows="5" cols="75"></textarea>
    <input asp-for="@Model[i].Id" type="hidden" />
}

<input type="submit" id="submitButton" value="@createOrUpdate" class="btn btn-primary" />

我的控制器方法:

public IActionResult Update(List<EvaluationsModel> evalRows)
{
   _dostuffWith(evalRows);
   return Redirect(toGet);
}

有时asp-for在隐藏字段中由于某些原因无法正常工作,我通常也使用值

 <input asp-for="@Model[i].Id" value"@Model[i].Id" type="hidden" />

恕我直言,你必须将 Id 添加到你的模型中,以防它不是更新而是创建

public ViewModel
{
public List<EvaluationsModel> EvaluationsModels {get;set;}
public int Id { get; set;}
{

并将隐藏字段 ID 添加到视图

@model ViewModel

....

<form id="evalForm" asp-action="@createOrUpdate">

<input type="hidden" asp-for="Id" value="@Model.Id" />

@for (var i = 0; i < Model.EvaluationsModels.Count; i++)

行动

public IActionResult Update(ViewModel viewModel)

最初的问题是复选框条目被加倍,添加 Id 值破坏了表单的提交。我没有在提交的原始代码中包含复选框,因为我认为这与问题无关。

经过大量搜索,这是我得出的(最终)答案:

  1. 升级到 dotnet core 5.0 或更高版本。

  2. Startup.cs中的Configure Services中,添加这一行:

    services.Configure(选项 => options.HtmlHelperOptions.CheckBoxHiddenInputRenderMode = CheckBoxHiddenInputRenderMode.None);

CheckBoxHiddenInputRenderMode有3个选项; “none”将阻止第二组复选框出现。其他两个选项将决定第二组的生成位置:在表单末尾(默认)或内联。

截至撰写本文时,我还没有找到任何说明如何实现此行为的文档。

问题是双重的:

  1. 3.1 及之前的布尔输入(又名复选框,未包含在我的原始问题中)的标签助手复制其条目,因此对于每个 <input asp-for="@Model[i].IsCorrect" /> 项目,我得到两个条目。 (MVC 这样做的原因是为了确保提交了一些东西,因为 HTML5 规范说如果一个复选框没有被选中,就不要提交任何东西。MVC 确保得到一些东西而不是什么都没有已提交。)

我看到了这个,但我觉得它并不奇怪,因为我还做了一些其他事情。所以表单发送所有常规条目,加上两个 bool 值(而不是像所有其他值一样只发送一个)。添加 ID 意味着我发送的内容超出了模型的预期。

  1. 控制器在收到太多 rows/entries 后只收到空值,因为我发送了重复的 boolean/checkbox 值,然后是 ID。根本没有关于此的错误报告。没有人说表单提交过多,或者条目太多。这部分让我怀疑 dotnet 核心框架是否存在错误。我不确定让它像这样默默地失败是故意的,还是疏忽,如果有办法检查的话。

但是问题解决了。

参考文献:the commit 新选项。