1

I'm trying to pass a ViewModel consisting of the 'List' entity and an array of 'Book' objects to the 'Create' Post method in my controller. The post will return the list but not any books. I'm not sure if I'm setting this up correctly or if I'm using the wrong model for the partial view.

ListWithBooksViewModel:

public class ListWithBooksViewModel
{
    public BookList List { get; set; }
    public Book[] Books { get; set; }
}

'Create' View:

@model LitList.Models.ListWithBooksViewModel
@using (Html.BeginForm("Create", "List", FormMethod.Post))
{
    <div>List Name: @Html.EditorFor(l => l.List.ListName)</div>
    <div>Subject of List: @Html.EditorFor(l => l.List.Subject)</div>

    Html.RenderPartial("AddBookPartial");
    Html.RenderPartial("AddBookPartial");
    Html.RenderPartial("AddBookPartial");

<p align="center">
    <input type="submit" value="Create List" />
</p>
}

'AddBookPartial' Partial View:

@model LitList.Domain.Entities.Book

@Html.BeginForm()
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <div class="form-group">
            @Html.LabelFor(model => model.BookName)
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookName)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Author)
            <div class="col-md-10">
                @Html.EditorFor(model => model.Author)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PublicationYear)
            <div class="col-md-10">
                @Html.EditorFor(model => model.PublicationYear)
            </div>
        </div>
    </div>

'Create' ActionMethod:

[HttpPost]
    public ActionResult Create(ListWithBooksViewModel newList)
    {
        BookList list = newList.List;

        if (ModelState.IsValid)
        {
            foreach (var b in newList.Books)
            {
                b.ListRefId = list.ListId;
            }
            list.Books = newList.Books;
            listRepo.SaveList(list);
            TempData["message"] = string.Format("{0} has been saved", list.ListName);
            return View("Index");
        }
        else
        {
            return View("Fail");
        }
Noah Hornak
  • 111
  • 2
  • 4
  • 15
  • Are you trying to dynamically add new `Book` objects to tour collection (in which case your doing it all wrong) –  Jul 14 '17 at 04:41
  • @Noah Harnak , just one thing do you want multiple book create form ?? – Shahzad Khan Jul 14 '17 at 04:45
  • @StephenMuecke I'm trying to create a 'BookList' object that contains 'Book' objects. I have two tables, one for each entity and made a FK in the 'Books' table in hopes of creating a one-to many relationship. I'm still pretty novice to MVC so if you could give me a sense of direction on a different approach I should take, I'd really appreciate it. – Noah Hornak Jul 14 '17 at 04:51
  • 1
    Start with [this answer](https://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308). I'll add a link with a more detailed answer using `BeginCollectionItem` shortly –  Jul 14 '17 at 04:54
  • 1
    Refer also [this answer](https://stackoverflow.com/questions/40539321/a-partial-view-passing-a-collection-using-the-html-begincollectionitem-helper/40541892#40541892) –  Jul 14 '17 at 04:56
  • @StephenMuecke Yes, Thank You! It's working now, those links really helped out a lot. Thanks again. – Noah Hornak Jul 14 '17 at 05:58

2 Answers2

0

Sorry but you cannot have "nested forms" or BeginForm inside a BeginForm.

You are nesting the BeginForm inside a PartialView with another BeginForm.

You can refer to this link as additional reference: Html.BeginForm inside of Html.BeginForm MVC3

Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
0

Plese add the loop and just add on RenderPartial pass your object.

@using (Html.BeginForm("Create", "List", FormMethod.Post))
{
    <div>List Name: @Html.EditorFor(l => l.List.ListName)</div>
    <div>Subject of List: @Html.EditorFor(l => l.List.Subject)</div>
    foreach (var book in Books)
    {
        Html.RenderPartial("AddBookPartial", book);
    }
    <p align="center">
        <input type="submit" value="Create List" />
    </p>
}
Shahzad Khan
  • 432
  • 2
  • 14
  • That will not work at all. Suggest you read the links in the question comments. –  Jul 14 '17 at 04:57
  • The 'Books' property of the 'ListWithBooksViewModel' returns null because it doesn't contain any books. I used ListWithBooksViewModel in hopes of passing the 'Book' objects created by the partial view and the List object created by the 'Create' view. – Noah Hornak Jul 14 '17 at 04:58
  • yes @NoahHornak add the condition for book array and check if array is not null. – Shahzad Khan Jul 14 '17 at 06:16