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.
public virtual ICollection<Ingredient> Ingredientstopublic IEnumerable<Ingredient> Ingredients { get; set; }(lose thevirtualand changeICollectiontoIEnumerable). Also, in your controller, pre-populate the list of ingredients with a single item (for testing) otherwise nothing will appear in your HTML.