【问题标题】:.NET Core submit passes all the data to the controller except for the id.NET Core 提交将所有数据传递给控制器​​,除了 id
【发布时间】:2021-11-26 01:35:43
【问题描述】:

.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);
}

【问题讨论】:

  • 您的列表项是否已经设置了 id?还是0?
  • 是的 - id 是在创建时设置的,它在隐藏输入中的表单中填充就好了。但是当它们在更新时传递给控制器​​时,控制器变量为空。
  • 我不确定,您是否尝试过传递@model 而不是@createOrUptade?​​span>
  • 隐藏的输入在呈现的 html 中是什么样子的?
  • 可能是因为"Model" != "evalRows"?

标签: c# .net-core asp.net-core-tag-helpers


【解决方案1】:

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

 <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)

【讨论】:

  • 如果你已经在使用asp-for="Id"我认为你不需要value="@Model.Id"
  • @PriyankPanchal 有时,它不能正确刷新并且 asp-for 正在变为空
【解决方案2】:

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

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

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

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

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

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

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

问题是双重的:

  1. 在 3.1 及之前的版本中,布尔输入(也称为复选框,不包含在我的原始问题中)的标签助手会重复其条目,因此对于每个 &lt;input asp-for="@Model[i].IsCorrect" /&gt; 项目,我得到两个条目。 (MVC 这样做的原因是为了确保提交某些内容,因为 HTML5 规范规定,如果未选中复选框,则根本不提交任何内容。MVC 确保提交内容而不是提交任何内容。)

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

  1. 控制器仅在获取太多行/条目后才收到 null,因为我发送的是重复的布尔值/复选框值,然后是 Id。根本没有关于此的错误报告。没有说表格提交过多,或者条目太多。这部分让我怀疑dotnet核心框架是否存在错误。我不确定让它像这样默默地失败是故意的,还是疏忽,如果有办法检查的话。

但是问题解决了。

参考:the commit 新选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 2014-09-22
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 1970-01-01
    相关资源
    最近更新 更多