C# 如何将对象添加到视图中的列表,并将修改后的列表发回控制器?(ASP.NET核心与mvc)

C# 如何将对象添加到视图中的列表,并将修改后的列表发回控制器?(ASP.NET核心与mvc),c#,asp.net-mvc,asp.net-core,model-view-controller,C#,Asp.net Mvc,Asp.net Core,Model View Controller,我的目的是创建具有复杂模型的编辑页面,在这里我还可以将对象添加到现有列表中,并可以更改其他字段,然后将所有数据发布回控制器,并将更改(或新对象)保存到数据库中。我正在使用ASP.NETCore3和mvc 我的编辑页面显示有关用户的一些信息以及相关数据的列表。我希望相关的数据列表是完全可编辑的,用户应该能够添加或删除对象从relatedDataList 这是我尝试过的,我不确定这是否是正确的方法。 然而,新插入的数据只是添加到表中,它们并没有发布回控制器,验证对它们也不起作用 我的另一个问题是,在

我的目的是创建具有复杂模型的编辑页面,在这里我还可以将对象添加到现有列表中,并可以更改其他字段,然后将所有数据发布回控制器,并将更改(或新对象)保存到数据库中。我正在使用ASP.NETCore3和mvc

我的编辑页面显示有关用户的一些信息以及相关数据的列表。我希望相关的数据列表是完全可编辑的,用户应该能够添加或删除对象从relatedDataList

这是我尝试过的,我不确定这是否是正确的方法。 然而,新插入的数据只是添加到表中,它们并没有发布回控制器,验证对它们也不起作用

我的另一个问题是,在有相关数据的表发生任何更改之后(提交表单之前),如何有效地计算相关数据列表中的值之和

我们非常感谢您提出的任何解决方案,谢谢您的宝贵时间

ObjectViewModel.cs

 public class ObjectViewModel
{
    public User user{ get; set; }
    public double SomeCountedValue{ get; set; } //not stored in db
    ...
    public List<RelatedData> RelatedDataList{ get; set; }
}
public class RelatedData
{
    public int Id { get; set; }

    public string Type { get; set; }

    [Required]
    public double Value { get; set; }

    ...some other data

    public int UserId { get; set; }
}
EditPage.cshtml

@model ViewModels.ObjectViewModel

   <form asp-action="Edit">
       //here i edit user data
       ...

       <table>
           <thead>
           ...
           </thead>
           <tbody id="relatedDataTableBody">
               @for (int i = 0; i < Model.RelatedDataList.Count; i++)
               {
                  <partial name="../Shared/Editors/_RelatedDataEditor.cshtml" for="@Model.RelatedData[i]" />
               }
          </tbody>
      </table>
      <button type="button" id="addRelatedData">Add</button>
      ...
      <input type="submit" value="save"/>
   </form>
   <script>...
       $("#addRelatedData").click(function () {
           $.ajax({
               url: "/UserController/AddRelatedData",
               cache: false,
               success: function (html) {$("#relatedDataTableBody").append(html); }
           });
           return false;
       });...
  </script>
@model Models.RelatedData

<tr class="tr">
      <td>
          <input hidden asp-for="@Model.Id" />
      <td>
          <input asp-for="@Model.Type" class="form-control"/>
          <span asp-validation-for="@Model.Type" class="text-danger"></span>
      </td>
  ...
      <td>
          <a value="Delete" onclick="$(this).closest('.tr').remove();">delete</a>
      </td>
</tr> ```
\u RelatedDataEditor.cshtml

@model ViewModels.ObjectViewModel

   <form asp-action="Edit">
       //here i edit user data
       ...

       <table>
           <thead>
           ...
           </thead>
           <tbody id="relatedDataTableBody">
               @for (int i = 0; i < Model.RelatedDataList.Count; i++)
               {
                  <partial name="../Shared/Editors/_RelatedDataEditor.cshtml" for="@Model.RelatedData[i]" />
               }
          </tbody>
      </table>
      <button type="button" id="addRelatedData">Add</button>
      ...
      <input type="submit" value="save"/>
   </form>
   <script>...
       $("#addRelatedData").click(function () {
           $.ajax({
               url: "/UserController/AddRelatedData",
               cache: false,
               success: function (html) {$("#relatedDataTableBody").append(html); }
           });
           return false;
       });...
  </script>
@model Models.RelatedData

<tr class="tr">
      <td>
          <input hidden asp-for="@Model.Id" />
      <td>
          <input asp-for="@Model.Type" class="form-control"/>
          <span asp-validation-for="@Model.Type" class="text-danger"></span>
      </td>
  ...
      <td>
          <a value="Delete" onclick="$(this).closest('.tr').remove();">delete</a>
      </td>
</tr> ```
@型号.相关数据
...
删除
```

首先,它应该是:

<partial name="" for="@Model.RelatedDataList[i]" />

而不是:

<partial name="" for="@Model.RelatedData[i]" />

您正在使用Ajax加载局部视图,如果您想实现模型绑定,作为解决方法,您可以从局部视图中附加html并设置当前索引,如下所示:

$("#addRelatedData").click(function () {

    var lastID = $("#relatedDataTableBody tr:last").children("td:first").find("input").eq(0).attr("id");
    var id =  parseInt(lastID.split("_")[1]) + 1;

    var html ="<tr class='tr'><td><input hidden='' type='number' data-val='true' data-val-required='The Id field is required.' id='RelatedDataList_"+id+"__Id' name='RelatedDataList["+id+"].Id'></td>"
    html += "<td><input class='form-control' type='text' id='RelatedDataList_" + id + "__Type' name='RelatedDataList[" + id + "].Type' >";
    html +="<span class='text-danger field-validation-valid' data-valmsg-for='RelatedDataList["+id+"].Type' data-valmsg-replace='true'></span></td>"
    html +="<td><a value='Delete' onclick=\"$(this).closest('.tr').remove();\">delete</a></td></tr>"
    $("#relatedDataTableBody").append(html);
});
$(“#添加相关数据”)。单击(函数(){
var lastID=$(“#relatedDataTableBody tr:last”).children(“td:first”).find(“input”).eq(0).attr(“id”);
var id=parseInt(lastID.split(“”)[1])+1;
var html=“”
html+=“”;
html+=“”
html+=“删除”
$(“#relatedDataTableBody”).append(html);
});

首先,它应该是:

<partial name="" for="@Model.RelatedDataList[i]" />

而不是:

<partial name="" for="@Model.RelatedData[i]" />

您正在使用Ajax加载局部视图,如果您想实现模型绑定,作为解决方法,您可以从局部视图中附加html并设置当前索引,如下所示:

$("#addRelatedData").click(function () {

    var lastID = $("#relatedDataTableBody tr:last").children("td:first").find("input").eq(0).attr("id");
    var id =  parseInt(lastID.split("_")[1]) + 1;

    var html ="<tr class='tr'><td><input hidden='' type='number' data-val='true' data-val-required='The Id field is required.' id='RelatedDataList_"+id+"__Id' name='RelatedDataList["+id+"].Id'></td>"
    html += "<td><input class='form-control' type='text' id='RelatedDataList_" + id + "__Type' name='RelatedDataList[" + id + "].Type' >";
    html +="<span class='text-danger field-validation-valid' data-valmsg-for='RelatedDataList["+id+"].Type' data-valmsg-replace='true'></span></td>"
    html +="<td><a value='Delete' onclick=\"$(this).closest('.tr').remove();\">delete</a></td></tr>"
    $("#relatedDataTableBody").append(html);
});
$(“#添加相关数据”)。单击(函数(){
var lastID=$(“#relatedDataTableBody tr:last”).children(“td:first”).find(“input”).eq(0).attr(“id”);
var id=parseInt(lastID.split(“”)[1])+1;
var html=“”
html+=“”;
html+=“”
html+=“删除”
$(“#relatedDataTableBody”).append(html);
});

您是否在
用户
某些CountedValue
对象中获取值?是的,并且已经在RelatedDataList中定义了相关数据。您是否在
用户
某些CountedValue
对象中获取值?是的,并且已经在RelatedDataList中定义了相关数据。谢谢,它似乎可以完美地与一个对象配合使用例外,客户端验证不适用于新添加的行,它绑定到controller中的列表,但只有在我第二次提交表单时,客户端验证才有效。这可能是因为模型只验证原始列表?是否可以以某种方式解决此问题?您的意思是ModelState没有在第一次提交事件中获得验证错误?确实如此,但对于服务器端验证中的默认消息->值“”无效(如果我使用空字段提交)。我有一些字段的自定义错误消息,例如此字段是必需的,然后在第二次提交事件中显示,并在发布到控制器操作之前在客户端验证字段。您还提到这是一个解决方案,实现这种编辑功能的正确方法是什么?在这里,我还必须在删除行时进行特殊处理,所以我只是想知道是否有正确的方法。。。。。很抱歉打扰您这么多,我最近才开始学习asp.net。嗯,谢谢。它似乎工作得很好,但有一个例外,客户端验证不适用于新添加的行,它绑定到控制器中的列表,但客户端验证仅在我第二次提交表单时有效。这可能是因为模型只验证原始列表?是否可以以某种方式解决此问题?您的意思是ModelState没有在第一次提交事件中获得验证错误?确实如此,但对于服务器端验证中的默认消息->值“”无效(如果我使用空字段提交)。我有一些字段的自定义错误消息,例如此字段是必需的,然后在第二次提交事件中显示,并在发布到控制器操作之前在客户端验证字段。您还提到这是一个解决方案,实现这种编辑功能的正确方法是什么?在这里,我还必须在删除行时进行特殊处理,所以我只是想知道是否有正确的方法。。。。。很抱歉打扰您,我最近才开始学习asp.net