在同一视图中创建多个相同类型的对象

Und*_*ker 5 c# asp.net entity-framework asp.net-mvc-4

在我的创建视图中,我想让用户可以创建一个对象列表(相同类型).因此,我在视图中创建了一个表,包括每行中的每个输入字段.各个"可创建"对象的行数是固定数.

让我们说有一个类书包括两个属性标题和作者,用户应该能够创建10个或更少的书.

我怎样才能做到这一点?

我不知道如何将对象列表(绑定)传递给控制器​​.我试过了:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ICollection<Book> bookList)
    {
        if (ModelState.IsValid)
        {
            foreach(var item in bookList)
                db.Books.Add(item);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(articlediscounts);
    }
Run Code Online (Sandbox Code Playgroud)

在视图中它是:

<fieldset>
    <legend>Book</legend>

    <table id="tableBooks" class="display" cellspacing="0" width="100%">
            <thead>
                <tr>
                    <th>Title</th>
                    <th>Author</th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < 10 ;i++ )
                {
                    <tr>
                        <td>
                            <div class="editor-field">
                                @Html.EditorFor(model => model.Title)
                                @Html.ValidationMessageFor(model => model.Title)
                            </div>
                        </td>
                        <td>
                            <div class="editor-field">
                                @Html.EditorFor(model => model.Author)
                                @Html.ValidationMessageFor(model => model.Author)
                            </div>
                        </td>
                    </tr>
                }
            </tbody>
        </table>

    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>
Run Code Online (Sandbox Code Playgroud)

由于booklist为null,它不起作用,我不知道如何将所有创建的对象放在此列表中.

如果您有任何建议,我将非常感激.

小智 0

您使用的事实@Html.EditorFor(model => model.Title)表明您已在视图中将模型声明为

@model yourAssembly.Book
Run Code Online (Sandbox Code Playgroud)

这允许只回发一个Book,因此 POST 方法需要是

public ActionResult Create(Book model)
Run Code Online (Sandbox Code Playgroud)

请注意,您当前的实现创建的输入看起来像

<input id="Title" name="Title" ... />
Run Code Online (Sandbox Code Playgroud)

这些name属性没有索引器(它们需要索引器等) name="[0].Title"name="[1].Title"因此无法绑定到集合,并且由于重复的id属性,它的 html 也无效。

如果您想创建正好 10 本书,那么您需要在 GET 方法中初始化一个集合并将该集合传递给视图

public ActionResult Create()
{
  List<Book> model = new List<Book>();
  for(int i = 0; i < 10;i++)
  {
    model.Add(new Book());
  }
  return View(model);
}
Run Code Online (Sandbox Code Playgroud)

并在视图中

@model yourAssembly.Book
@using (Html.BeginForm())
{
  for(int i = 0; i < Model.Count; i++)
  {
    @Html.TextBoxFor(m => m[i].Title)
    @Html.ValidationMessageFor(m => m[i].Title)
    .... // ditto for other properties of Book
  }
  <input type="submit" .. />
}
Run Code Online (Sandbox Code Playgroud)

当您发布到时,它现在将绑定到您的集合

public ActionResult Create(List<Book> bookList)
Run Code Online (Sandbox Code Playgroud)

请注意,该集合应该是List<Book>在您需要返回视图时使用的。

但是,这可能会强制用户创建所有 10 本书,否则验证可能会失败(如您使用的建议@Html.ValidationMessageFor())。更好的方法是使用BeginCollectionItem帮助器方法(参考示例)或根据此答案的Book客户端模板在视图中动态添加新项目。