将模型从视图传递到控制器时不会填充虚拟属性

Virtual properties don't get populated when passing model from view to controller

当我 运行 程序并在控制器方法中设置断点时,我可以单步执行并看到 recipe.Name 和 recipe.ID 已正确填充,但是 recipe.Ingredients 为空。

我忽略了什么?这是我的相关代码:

型号:

public class Recipe
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Ingredient> Ingredients { get; set; }
}

查看:

@model Cookbook.Models.Recipe
// removed irrelevant code for this question
<dt>@Html.DisplayNameFor(model => model.Name)</dt>
<dd>@Html.DisplayFor(model => model.Name)</dd>
<dd>
   <table class="table">
        <tr><th>Ingredient</th></tr>
        @foreach (var item in Model.Ingredients)
        {
            <tr><td>@Html.DisplayFor(model => item.Name)</td></tr>
        }
    </table>
</dd>
<p> @Html.ActionLink("Export Data", "ExportData", Model)</p>

控制器:

public ActionResult ExportData (Recipe recipe)
{
    //I am dynamically building an XML file by constructing it line by line
    string xml = recipe.Name + "\r\n\r\n"; //Here, Name is populated
    //Here, recipe.Ingredients is empty even though it appears in the view
    foreach(Ingredient ing in recipe.Ingredients)
    {
        xml = xml + ing.Ingredient.Name + "\r\n";
    }
}

您不能将包含集合(或复杂对象)的 属性 的模型传递给使用 @Html.ActionLink() 的 get 方法。在内部,该方法通过对模型中的每个 属性 调用 .ToString() 方法来生成查询字符串值。在您的情况下,它正在生成

...?ID=someValue&Name=someValue&Ingredients=System.Collections.Generic.ICollection<Ingredient>

为了绑定到您的模型,需要

...?....&Ingredients[0].Name=someValue&Ingredients[1].Name=someValue&...

相反。将模型的 ID 传递给方法,然后再次获取模型(就像您在生成此视图的 GET 方法中所做的那样)来构建您的 xml 文件

@Html.ActionLink("Export Data", "ExportData", new { id = Model.ID })

public ActionResult ExportData (int ID)
{
  var recipe = db.Recipies.Where(r => r.ID = ID).FirstOrDefault();
  ....
}