ASP.NET MVC 5 如何在同一视图中编辑 Parent 和 List<> 类型 Child

Posted

技术标签:

【中文标题】ASP.NET MVC 5 如何在同一视图中编辑 Parent 和 List<> 类型 Child【英文标题】:ASP.NET MVC 5 How to edit Parent and List<> type Child in same view 【发布时间】:2021-04-20 16:20:20 【问题描述】:

我需要在同一个视图中编辑一个 List 类型的类及其子类,但我不知道如何让子类在同一个视图中编辑。

假设我有这些课程:

public class Parent

    public int PValue1  get; set; 
    public int PValue2  get; set; 
    public int PValue3  get; set; 

    public virtual List<ChildItem> Childs  get; set; 


public class ChildItem

    public int CValue1  get; set; 
    public int CValue2  get; set; 

观点:

@model MyNamespace.Parent

@using (html.BeginForm("SaveParent", "Index"))

    <label>Parent Value 1</label>
    @Html.TextBoxFor(m=> m.PValue1, "", new  @class = "form-control" )

    <label>Parent Value 2</label>
    @Html.TextBoxFor(m=> m.PValue2, "", new  @class = "form-control" )

    <label>Parent Value 3</label>
    @Html.TextBoxFor(m=> m.PValue3, "", new  @class = "form-control" )

    @*  WHAT TODO? *@

    <table>
        <thead>
            <tr>
            <th>Child Value 1</th>
            <th>Child Value 2</th>
            </tr>
        </thead>
        <tbody>
        @foreach(ChildItem item in Model.Childs)
            <tr>
            <td>@item.CValue1</td>
            <td>@item.CValue2</td>
            </tr>
        
        </tbody>
    </table>

    <button type="submit" class="btn btn-primary">Save</button>

我需要在“WHAT TODO”区域为Childs 孩子创建一个插入代码。 我尝试将 PartialView 与以下内容一起使用:

@Html.Partial("_MyPartialView", Model.Childs)

然后在 PartialView 中创建另一个表单以使用 Insert(ChildItem child) 控制器,但我也无法实现这一点。我不知道如何将第二个表单添加到模型中,因为它是一个列表。

现在可能很明显,但我是 ASP.NET MVC 的新手,并且习惯于旧的 WebForms,所以仍然了解一些东西。

我的目标是完成这样的工作视图:

【问题讨论】:

【参考方案1】:

好的,所以通过进一步研究,我发现我不需要嵌套表单或部分视图,而是需要多个提交按钮和多个表单操作。 我得到了我需要的东西,显然它真的很基础,所以我想我可以发布我自己的解决方案来解决我自己的问题,也许可以帮助其他有同样问题的人。 所以,从我替换的视图开始:

    @*  WHAT TODO? *@

有了这个:

    <label>Child Value 1</label>
    <input type="number" name="CValue1" />
    <label>Child Value 2</label>
    <input type="number" name="CValue1" />
    <!--This is the real trick! -->
    <input type="submit" formaction="AddChild" formmethod="post" />  

formaction="AddChild" 触发控制器中的 AddChild() 操作,提交父模型以及 CValue1CValue2 输入。 但是模型的Childs 属性始终是null,所以在执行AddChild 操作后,我只得到了最后添加的ChildItem。 为了解决这个问题,我必须让我的控制器在我的Parent 中识别List&lt;ChildItem&gt;,在帖子中单独发送它。 所以,我不得不从这里更改列表视图:

@foreach(ChildItem item in Model.Childs)
   <tr>
     <td>@item.CValue1</td>
     <td>@item.CValue2</td>
   </tr>

到这里:

 @for(int x = 0; x < Model.Childs.Count; x++) 
  <tr>
     <td>@Html.DisplayFor(m => m.Childs[x].CValue1)</td>
     <td>@Html.DisplayFor(m => m.Childs[x].CValue2)</td>
     <td> <button type="submit" formaction="DeleteChild" name="ChildID" value="@Model.Childs[x].ID" formmethod="post">X</button>
      @Html.HiddenFor(m => m.Childs[x].ID)
      @Html.HiddenFor(m => m.Childs[x].CValue1)
      @Html.HiddenFor(m => m.Childs[x].CValue2)
     </td>
  </tr>               
  

隐藏字段存储控制器绑定的所有信息。 由于每一行都有索引x,所以在提交表单时,控制器可以正确地将所有子元素绑定到Child属性。

添加 Child 的控制器:

public ActionResult AddChild(Parent parent, int CValue1, int CValue2)
  if (parent.Childs == null)
    parent.Childs = new List<ChildItem>();
  parent.Childs.Add(new ChildItem()
    ID = parent.Childs.Count,  //This will be removed/improved later
    CValue1 = CValue1,
    CValue2 = CValue2
  );
  return View("Index", parent);

我还实现了DeleteChild 操作:

public ActionResult DeleteChild(Parent parent, int ChildID)
   if (parent != null)
      parent.Childs.Remove(parent.Childs.FirstOrDefault(c => c.ID == ChildID));
      return View("Index", parent);

它仍然缺少所有数据库代码,但这是下一步!

【讨论】:

以上是关于ASP.NET MVC 5 如何在同一视图中编辑 Parent 和 List<> 类型 Child的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core MVC 的同一视图中添加/创建多个一对多关系

使用 ASP.NET MVC,如何最好地避免同时编写添加视图和编辑视图?

在 ASP.Net MVC 中的同一视图中分离两个表单

如何在 ASP.Net MVC 5 视图中获取 ApplicationUser 的自定义属性值?

如何只显示数据库中最近的 5 条记录 - ASP.NET MVC

如何从 ASP.NET MVC 视图显示存储在数据库中的 HTML?