2

Im trying to implement a way how to enter recipes correctly, so far I have the following:

Recipe.cs

public class Recipe
{
    [Key]
    public int RecipeId { get; set; }
    [Required]
    public string Name { get; set; }
    public string Subtitle { get; set; }
    public int Serving { get; set; }
    public string Instructions { get; set; }
    public virtual ICollection<Ingredient> Ingredients
}

Ingredient.cs

public class Ingredient
{
    [Key]
    public int IngredientId { get; set; }
    public string Name { get; set; }
    public string Amount { get; set; }
    public virtual ICollection<Recipe> Recipes { get; set; }
}

In my Form, I want to Add the Ingredients Inline, with JavaScript Rendering a new pair of fields if needed.

(The ViewModel is nothing else than a class holding an instance of Recipe)

Create.cshtml

 @model Vineyard.WebUI.Areas.Admin.Models.RecipeViewModel
 <div class="span9">
    <h2>Create a new Recipe</h2>
    @using (@Html.BeginForm("Create", "Recipes", FormMethod.Post))
    {
        <fieldset>
            @Html.LabelFor(r => r.Recipe.Name)
            @Html.TextBoxFor(r => r.Recipe.Name)
        </fieldset>
        <fieldset>
            @Html.LabelFor(r => r.Recipe.Subtitle)
            @Html.TextBoxFor(r => r.Recipe.Subtitle)
        </fieldset>
        <div id="ingredients">
            @Html.EditorFor(r => r.Recipe.Ingredients, "Ingredient")
        </div>
        <a href="#" id="addIngredient" class="btn btn-info">Add Ingredient</a>
        <fieldset>
            @Html.LabelFor(r => r.Recipe.Serving)
            @Html.TextBoxFor(r => r.Recipe.Serving)
        </fieldset>
        <fieldset>
            @Html.LabelFor(r => r.Recipe.Instructions)
            @Html.TextAreaFor(r => r.Recipe.Instructions)
        </fieldset>
        <input type="submit" value="Save Recipe" />
    }
  </div>

Shared/EditorTemplates/Ingredient.cshtml

@model Vineyard.Core.Entities.Ingredient

<div class="ingredient form-inline">
  @Html.LabelFor(r => r.Amount)
  @Html.TextBoxFor(r => r.Amount)
  @Html.LabelFor(r => r.Name)
  @Html.TextBoxFor(r => r.Name)
</div>

In the rendered HTML tough, I see the following:

<input id="Recipe_Ingredients_Amount" name="Recipe.Ingredients.Amount" type="text" value="">

Which leads my to believe, that it does not Add the Ingredient as a Member of the Collection, but as a full blown Object by itself. Shouldnt it have an index referencing to it? (Based of this http://jarrettmeyer.com/post/2995732471/nested-collection-models-in-asp-net-mvc-3)

When I look at the Model, that is being passed back to the controller, the Ingredients Part is null

So, Im wondering - what am I missing here or doing wrong, that can be changed to actually populate the Collection correctly? From there, I can handle it in the controller to be saved in the right format.

4
  • Which leads my to believe - Have to tried it? It's best to see what happens before assuming something does or doesn't work and posting a hypothetical question about something that may not be a problem. Commented Jul 17, 2013 at 19:18
  • Yes, I have tried it. As said above, the Model passes back null for the Ingredients. Thats what actually leads me to this. - "Which leads me to believe" - I might be wrong, but its not rendering the Ingredient as Part of the Collection but as a single object. Commented Jul 17, 2013 at 19:21
  • Change public virtual ICollection<Ingredient> Ingredients to public IEnumerable<Ingredient> Ingredients { get; set; } (lose the virtual and change ICollection to IEnumerable). Also, in your controller, pre-populate the list of ingredients with a single item (for testing) otherwise nothing will appear in your HTML. Commented Jul 17, 2013 at 19:30
  • Did this - Actually changed it to IList - Worked like magic, thank you :) Commented Jul 17, 2013 at 20:23

1 Answer 1

1

Change

public virtual ICollection<Ingredient> Ingredients

to

public IEnumerable<Ingredient> Ingredients { get; set; } 

(lose the virtual and change ICollection to IEnumerable).

Also, in your controller, pre-populate the list of ingredients with a single item (for testing) otherwise nothing will appear in your HTML.

This answer was converted from my comment

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.