【问题标题】:Bind model with array property to form in ASP.NET Core MVC使用数组属性绑定模型以在 ASP.NET Core MVC 中形成
【发布时间】:2018-10-05 14:44:51
【问题描述】:

我试图弄清楚如何将表单元素绑定到包含数组或可枚举属性的模型。此表单应可用于添加新对象或编辑现有对象。

下面是一个精简的例子。

如果 Levels 不包含任何元素(例如 create),则不会呈现 Level 字段的行。您应该向 Level 数组添加一个空元素还是应该添加一行空字段?但是如何使用 asp-for 属性来做到这一点。

如果 Levels 包含元素(例如 edit),则渲染 Level 字段的行。但是,在Edit 方法中发布model.Levels 时是null

任何想法如何最好地实现这一点?

要绑定的模型

public class CarparkModel
{
  [HiddenInput]
  public int Id { get; set; }
  public string Name { get; set; }
  public Level[] Levels { get; set; }
}

public class Level
{
   [HiddenInput]
   public int Id { get; set; }
   public string Description { get; set; }
   public int NrOfSpaces { get; set; }
}

主视图

@model CarparkModel

<form method="POST">
  <input asp-for="Id">
  <div>
    <label asp-for="Name"></label>
    <input asp-for="Name">
  </div>
  <table>
    <tr>
      <th>Description</th>
      <th>Nr of spaces</th>
    </tr>
  @foreach (Level level in Model.Levels)
  {
    <tr>
      <td><input asp-for="Description"></td>
      <td><input asp-for="NrOfSpaces"></td>
    </tr>
  }
    <tr>
      <td colspan="2>
        <!-- Click = new row of Level fields added -->
        <button type="button">Add level</button>
      </td>
    </tr>
  </table>
  <button type="submit">Save</button>
</form>

控制器

public class CarparkController
{
  [HttpGet]
  public IActionResult Create()
  {
    return View(new CarparkModel());
  }

  [HttpPost]
  public IActionResult Create(CarparkModel model)
  {
    if (ModelState.IsValid)
    {
      _repository.Save(model);
      return RedirectToAction("index");
    }

    return View(model);    
  }

  [HttpGet]
  public IActionResult Edit(int id)
  {
    return View(_repository.Get(id));
  }

  [HttpPost]
  public IActionResult Edit(CarparkModel model)
  {
    if (ModelState.IsValid)
    {
      _repository.Save(model);
      return RedirectToAction("index");
    }

    return View(model);    
  }
}

【问题讨论】:

  • 如果您希望能够在表单中发回项目,请不要使用foreach。使用带有索引命名的for循环。
  • 如果您想动态地向集合中添加新项目,请参考this answer 了解一些选项,参考this one 了解使用BeginCollectionItem 的详细实现。
  • 由于使用core-mvc,所以需要使用this version of BeginCollectionItem

标签: c# asp.net-core .net-core asp.net-core-mvc asp.net-core-2.1


【解决方案1】:

如果您希望能够在表单中发回项目,请不要使用foreach。使用带有索引命名的for循环。

@model CarparkModel

<form method="POST">
  <input asp-for="Id">
  <div>
    <label asp-for="Name"></label>
    <input asp-for="Name">
  </div>
  <table>
    <tr>
      <th>Description</th>
      <th>Nr of spaces</th>
    </tr>
  @for(var index = 0, index < Model.Levels.Length, index++)
  {
    <tr>
      <td><input asp-for="@Model.Levels[index].Description"></td>
      <td><input asp-for="@Model.Levels[index].NrOfSpaces"></td>
    </tr>
  }
    <tr>
      <td colspan="2">
        <!-- Click = new row of Level fields added -->
        <button type="button">Add level</button>
      </td>
    </tr>
  </table>
  <button type="submit">Save</button>
</form>

在表单中发布集合时需要索引来重建集合。

【讨论】:

  • 谢谢,这给了我部分问题的答案。现在我需要解决空数组的绑定字段问题。
  • 如果 [index] 是可选的会很好,而可以使用 []... 使用 javascript 添加/删除项目会很痛苦...
猜你喜欢
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 2022-06-11
  • 2021-06-27
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
相关资源
最近更新 更多