简体   繁体   English

ASP.net MVC5-For循环发布单个项目,但不发布集合

[英]ASP.net MVC5 - For loop posts single item but not the collection

I am creating a new recipe entry form and I am finding two interesting problems: 我正在创建一个新的食谱输入表格,发现两个有趣的问题:

  1. The Ingredient does not post to the recipe collection, and 成分不会发布到配方集合中,并且
  2. The Form will only post a single ingredient and sends null when I have the parameter set to a collection. 当我将参数设置为集合时,表单将仅发布一种成分并发送null。

Ideally, I'd like the ingredient collection to be under the recipe item, but I'll settle for just getting the ingredient collection to write to the parameter. 理想情况下,我希望配料集合位于配方项下,但我会选择使配料集合写入参数。

Here are the two models (Generated by entity framework): 这是两个模型(由实体框架生成):

Recipe: 食谱:

    public int recipeId { get; set; }

    [Required]
    [StringLength(255)]
    [DisplayName("Name")]
    public string name { get; set; }

    [DisplayName("Category")]
    public int? mealCategoryId { get; set; }

    [DisplayName("Preperation Time")]
    public int? prepTime { get; set; }

    [DisplayName("Cook Time")]
    public int? cookTime { get; set; }

    [DisplayName("Stand Time")]
    public int? standTime { get; set; }

    [DisplayName("Serving Size")]
    public int? servingSize { get; set; }

    [DisplayName("Status")]
    public int recipeStatusId { get; set; }

    [DisplayName("Description")]
    [UIHint("Multiline")]
    public string description { get; set; }

    public virtual ICollection<Direction> Directions { get; set; }

    public virtual ICollection<Image> Images { get; set; }

    public virtual ICollection<Ingredient> Ingredients { get; set; }

    public virtual MealCategory MealCategory { get; set; }

    public virtual ICollection<Nutrition> Nutritions { get; set; }

    public virtual ICollection<Rating> Ratings { get; set; }

    public virtual RecipeStatus RecipeStatus { get; set; }
}

Ingredient: 成分:

public partial class Ingredient
    {
        public int ingredientId { get; set; }

        public int? recipeId { get; set; }

        public int? subCategoryId { get; set; }

        public int measurementId { get; set; }

        public int amount { get; set; }

        public virtual Recipe Recipe { get; set; }

        public virtual SubCategory SubCategory { get; set; }

        public virtual Measurement Measurement { get; set; }

    }

View Code: 查看代码:

   <div class="form-horizontal">
        <h4>Ingredients</h4>
        <hr />
        <table class="table IngredientList">
            <tr>
                <th>
                    @Html.LabelFor(model => model.Recipe.Ingredients)
                </th>
                <th>
                    @Html.LabelFor(model => model.SelectedMeasurementId)
                </th>
                <th>
                    @Html.Label("Amount")
                </th>
            </tr>

            @for (int i = 0; i < Model.Recipe.Ingredients.Count; i++)
            {
                <tr>
                    <td>
                        @Html.DropDownListFor(m => Model.Recipe.Ingredients.ElementAt(i).ingredientId, Model.SubIngredients, new { @class = "form-control input-block-level" })
                    </td>
                    <td>
                        @Html.DropDownListFor(m => Model.Recipe.Ingredients.ElementAt(i).measurementId, Model.Measurements, new { @class = "form-control input-block-level" })
                    </td>
                    <td>
                        @Html.TextBoxFor(m => Model.Recipe.Ingredients.ElementAt(i).amount, new { @class = "form-control input-block-level" })
                    </td>
                </tr>
            }

        </table>
</div>

Controller: 控制器:

   [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Recipe recipe, int SelectedCategoryId, List<Ingredient> Ingredients)

    {
        recipe.mealCategoryId = SelectedCategoryId;
        recipe.recipeStatusId = 1;

        if (ModelState.IsValid)
        {
            dbContext.Entry(recipe).State = EntityState.Added;
            dbContext.SaveChanges();
            return RedirectToAction("Details", new {id = recipe.recipeId});
        }

        return View(recipe);
    }

So, if I have the parameter set to List Ingredients then null is returned. 因此,如果我将参数设置为“列出成分”,则返回null。 If I have it set to Ingredient Ingredients then I get only the first of four ingredients. 如果将其设置为“成分成分”,那么我只会得到四种成分中的第一种。 (I have the model set to create 4 ingredient records upon loading.) (我将模型设置为在加载时创建4个成分记录。)

My question is: How do I get it to pass the collection of ingredients? 我的问题是:如何使它通过配料收集?

EDIT: 编辑:

I have confirmed that the request is sending all 4 of the ingredients over. 我已经确认请求已将所有4种配料都发送过来。 It seems to be a problem with the binding. 绑定似乎有问题。

Create your own ViewModels to hold Data, do not use Entity Frameworks pre generated classes for Model Binding. 创建自己的ViewModel来保存数据,不要将Entity Frameworks预先生成的类用于模型绑定。 Here's a very basic example for Proof of Concept 这是概念证明的一个非常基本的例子

public class Recipe
{
  public int RecipeId {get; set;}
  public List<Ingredients> Ingredient {get; set;}
} 

public class Ingredients
{
  public string Name {get; set;}
  public string Amount {get; set;}
}

public ActionResult Index()
{
   Recipe model = new Recipe();
   model.RecipeId = 1;
   model.Ingredient = new List<Ingredients>();//Better if done inside Constructor

   model.Ingredient.Add(new Ingredients{Name = "Salt", 
                                        Amount = "A Pinch"});
   model.Ingredient.Add(new Ingredients{Name = "Hot Sauce", 
                                        Amount = "HOT HOT HOT!"});   
  return View(model);
}

View 视图

@Html.TextBoxFor(x => x.RecipeId)

  for (int i = 0; i < Model.Ingredient.Count; i++)
    {
          @Html.TextBoxFor(modelItem => Model.Ingredient[i].Name)
          @Html.TextBoxFor(modelItem => Model.Ingredient[i].Amount)
    }

And post it and it will bind 并将其发布,它将绑定

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM