2

New to MVC and just struggling with retrieving my form data from a List<>. In my controller, I am able to get my Name value (recipe name) correctly but cannot get the Ingredient Name value, always coming back as NULL?

Below are some code snippets from my project.

MODEL

public class Recipe
{

    [Required]
    public string Name { get; set; }
    public List<Ingredient> Ingredients { get; set; }

    public Recipe()
    {
        Ingredients = new List<Ingredient>()
        {
            new Ingredient()
        };

    }
}

public class Ingredient
{
    public string Name { get; set; }
}

VIEW

@using (Html.BeginForm("CreateEdit", "Recipe"))
    {
        @Html.ValidationSummary()
        <div class="form-group">
            @Html.LabelFor(x => x.Name, "Name")
            @Html.TextBoxFor(x => x.Name, new { @class = "form-control" })
            @Html.ValidationMessageFor(x => x.Name)
        </div>

        <h2>Ingredient(s)</h2>
        <div class="form-group">
            @Html.LabelFor(x => x.Ingredients.FirstOrDefault().Name, "Name")
            @Html.TextBoxFor(x => x.Ingredients.FirstOrDefault().Name, new { @class = "form-control" })
        </div>
        <div class="form-group">
            <input class="btn btn-primary" type="submit" text="submit" />
        </div>
    }

CONTROLLER

[HttpPost]
public ActionResult CreateEdit(Recipe recipe)
{           
   var recipeName = recipe.Name // <--- Works
   var ingredientName = recipe.Ingredients.FirstOrDefault().Name; //<--- NULL value

   return View(recipe);
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Sanchez89
  • 64
  • 1
  • 6
  • 1
    Have a look at this: http://stackoverflow.com/a/23553225/3585278 – Danieboy Nov 20 '16 at 11:54
  • 1
    You cannot use `.FirstOrDefault()` in the view - you need to use a `for` loop or custom `EditorTemplate` for `Ingredient` - refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943). But if you only want one `Ingredient`, why are you using `List`? –  Nov 20 '16 at 11:54
  • 1
    @Danieboy thanks that solved my problem – Sanchez89 Nov 20 '16 at 12:18
  • @StephenMuecke the form will eventually allow the ability to add multiple ingredients to a recipe, that's my next challenge :) – Sanchez89 Nov 20 '16 at 12:19
  • The read the link I gave you to understand what the html you generate needs to be (and how to achieve it) –  Nov 20 '16 at 12:20
  • 1
    And if you want to dynamically add (and remove) collection items in the view, refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Nov 20 '16 at 12:28

1 Answers1

1
  1. Ingredients is a property of class Recipe and is of type List<Ingredient>.
  2. The action to which you are posting CreateEdit has a parameter Recipe.

To bind list objects we need to provide an index for each items. Like for example

<form method="post" action="/Home/CreateEdit">

    <input type="text" name="recipe.Ingredients[0].Name" value="Red Sauce" />

    <input type="text" name="recipe.Ingredients[1].Name" value="White Sauce" />    

</form>

Read this link - http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ to understand this better.

Yasser Shaikh
  • 46,934
  • 46
  • 204
  • 281