0

我正在寻找一种方法来从我从数据库中检索的项目列表中进行选择。我将这些项目发送到一个视图,我想从列表中进行选择并将其返回给控制器以填充数据库中的辅助表。我可以将项目传递给视图并让它们显示,但我似乎无法将这些项目传递回控制器。

控制器调用(再次更新):

    public ActionResult Create()
    {
        var myMeal = new CreateMeal();
        List<ProductsToInclude> pti = new List<ProductsToInclude>();
        myMeal.ProductsToInclude = pti;
        IList<Product> prods = db.Products.ToList();


        foreach(var prod in prods)
        {
            pti.Add(new ProductsToInclude { Product = prod });
        }

        return View(myMeal);
    }

    //
    // POST: /Meal/Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(CreateMeal myMeal)
    {
        if (ModelState.IsValid)
        {
            /* Add code to handle my meal and create a meal for data base*/
            db.Meals.Add(meal);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(pti);
    }

ProductsToInclude 视图模型

public class ProductsToInclude
{
    public Product Product { get; set; }
    public Boolean Include { get; set; }
}

新的 CreateMeal 视图模型:

public class CreateMeal
{
    public String Name { get; set; }
    public IList<ProductsToInclude> ProductsToInclude { get; set; }
}

创建视图:

@model MealPlanner.ViewModels.CreateMeal

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Meal</legend>

        <div>
          @Html.LabelFor(m => m.Name)
           @Html.TextBoxFor(m => m.Name)
        </div>

        <div>
            @Html.EditorFor(m => m.ProductsToInclude)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

和编辑器 Templete(更新):

@model MealPlanner.ViewModels.ProductsToInclude

<tr>
    <td>
        @Html.CheckBoxFor(m => m.Include)
    </td>
    <td>
        @Model.Product.Name 
        @Model.Product.Quantity 
        @Model.Product.unit.UnitName
        @Html.HiddenFor(m => m.Product.Name) 
        @Html.HiddenFor(m => m.Product.Quantity) 
        @Html.HiddenFor(m => m.Product.unit.UnitName)
    </td>
</tr>

膳食模型:

public class Meal
{
    public int MealId { get; set; }
    public String Name { get; set; }
    //public virtual IList<Product> Products { get; set; }
    public int UserId { get; set; }
}

更新:

切换到 EditorTemplete 我无法显示它。我现在收到一个错误 myMeal.ProductsToInclude.Add(new ProductsToInclude { Product = prod, Include = false}); 在创建方法中。prod 已填充,其中包含 8 个产品。

4

1 回答 1

0

这里有两个基本问题。(第三,您没有将任何模型传递给视图,但您的视图需要一个 Meal 对象)首先,您发布的模型与渲染的模型不同。因此,当您发布表单时,它不会识别 Meal.Name 对象,因为发布操作需要一个 ProductsToInclude 列表。

如果您不打算更改 Meal.Name 的值,那么我建议使用 DisplayFor 而不是 EditorFor 来呈现它。

其次,您呈现表单字段的方式不会创建正确的命名结构以允许默认模型绑定器绑定到集合。您可以使用 EditorTemplates,这是我更喜欢的方法。

您将创建一个名为 ProductsToInclude.cshtml 的编辑器模板,而不是使用 Partial,将模型类型设置为 ProductsToInclude(没有 List),然后像单个项目一样呈现。您还需要将表格和标题信息移到主视图中。

EditorTemplates 无需执行任何特殊操作即可处理这种情况。它们会自动迭代集合,并正确呈现名称。尽可能使用它们。

<div>
    <table>
        <tr>
            <th>
                @Html.DisplayName("Include")
            </th>
            <th>
                @Html.DisplayName("Available Products")
            </th>
            <th></th>
       </tr>
       @Html.EditorFor(m => m.ProductsToInclude)
    </table>
</div>

您的 ProductsToInclude.cshtml 应位于 ~/Views/Shared 或本地视图文件夹中名为 EditorTemplates 的文件夹中。

@model ProductsToInclude
<tr>
    <td>
        @Html.CheckBoxFor(m => m.Include)
    </td>
    <td>
        @Html.DisplayFor(m => m.Product.Name) 
        @Html.DisplayFor(m => m.Product.Quantity) 
        @Html.DisplayFor(m => m.Product.unit.UnitName)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=Model.PrimaryKey }) |
        @Html.ActionLink("Details", "Details", new { id=Model.PrimaryKey }) |
        @Html.ActionLink("Delete", "Delete", new { id=Model.PrimaryKey })
    </td>
</tr>
于 2013-04-28T18:56:34.147 回答