【问题标题】:MVC Model binding issue - list of objectsMVC 模型绑定问题 - 对象列表
【发布时间】:2015-07-14 14:34:32
【问题描述】:

场景是一个购物篮 - 用户将更新数量的文本框并点击更新按钮。 目前,点击更新按钮时,Action 被点击,但模型属性全部为空。

我的第一个想法是绑定存在一些问题,因为每一行的控件 id 都发生了变化。

我的想法正确吗?如果是这样,我该如何解决?

编辑:我也尝试使用 for 循环,而不是 foreach,但这也不起作用。 我所有的代码都在下面:

<table class="order-table order-table-nomargin order-table-noborder hidden-xs hidden-sm">
  <thead>
    <tr><th>Products</th><th></th><th>Price</th><th>Qty.</th><th>Total</th></tr>
  </thead>
  <tbody>
    @foreach (Nop.Web.Models.Custom.CustomOrderLine ol in Model.Cart.OrderLines)
    {    
      @Html.DisplayFor(m => ol)
    }      
  </tbody>
</table> 

这是我的 displayFor 模板:

@model Nop.Web.Models.Custom.CustomOrderLine
<tr>
    <td>
        <img alt="book image" src="@Model.Image.Media.Url"  width="100" />
    </td>
    <td>
        @Html.ActionLink(@Model.Title, "Product", "Catalog", new { seName = @Model.SeName }, null)<br />
        @*@Html.DisplayFor(m => m.Title)<br />*@ By: @Html.DisplayFor(m => m.Author)<br />
        Published date: @Html.DisplayFor(m => m.PublishedDate)<br />
        Format: @Html.DisplayFor(m => m.Format)
    </td>
    <td>
        <p class="onlinePrice">
            <em>@Html.DisplayFor(m => m.PriceWithDiscount)</em></p>
        <p class="saving">
            <em>@Html.DisplayFor(m => m.PriceDiscount)</em></p>
        <p class="rrp">
            RRP: <em>@Html.DisplayFor(m => m.Price)</em></p>
    </td>
    <td>
        @using (Html.BeginForm("UpdateCart", "CustomCart"))
        { 
            string test = Model.Isbn13;
            int QuantTest = Model.Qty;

            @Html.EditorFor(m => Model.Qty)
            @Html.HiddenFor(m => m.Isbn13)
            //@Html.TextBoxFor(m => m.Qty)
            <input type="submit" value="Update" />
        }
    </td>
    <td>
        <p class="subTotal numeric-right">@Html.DisplayFor(m => m.Total)</p>
    </td>
</tr>

我的控制器动作:

[HttpPost]
public ActionResult UpdateCart(CustomOrderLine model)
{

    //add code here


    return XXX;
}

这是使用 foreach 循环生成的 HTML:

<table class="order-table order-table-nomargin order-table-noborder hidden-xs hidden-sm">
<thead>
<tr><th>Products</th><th></th><th>Price</th><th>Qty.</th><th>Total</th></tr>
</thead>
<tbody>
<tr>
    <td>
        <img alt="book image" src="http://media.harrypotter.bloomsbury.com/rep/s/9781408855652_309039.jpeg"  width="100" />
    </td>
    <td>
        <a href="/uk/harry-potter-and-the-philosophers-stone-9780747558194-9781408855652">Harry Potter and the Philosopher&#39;s Stone </a><br />
         By: J.K. Rowling<br />
        Published date: 01-09-2014<br />
        Format: Paperback
    </td>
    <td>
        <p class="onlinePrice">
            <em>6.29</em></p>
        <p class="saving">
            <em>Save ВЈ0.70 (10%)</em></p>
        <p class="rrp">
            RRP: <em>6.99</em></p>
    </td>
    <td>

<form action="/CustomCart/UpdateCart" method="post">
<input class="text-box single-line" data-val="true" data-val-number="The field Qty must be a number." data-val-required="&amp;#39;Qty&amp;#39; must not be empty." id="ol_Qty" name="ol.Qty" type="text" value="1" />
<input id="ol_Isbn13" name="ol.Isbn13" type="hidden" value="9781408855652" />            
<input type="submit" name="123" id="123" value="Update 2" />
</form>    </td>
    <td>
        <p class="subTotal numeric-right">6.29</p>
    </td>
</tr>
</tbody>
</table> 

【问题讨论】:

  • 您能展示一下使用for 循环时的样子吗?你能在提交表单时显示 POSTed 数据的样子吗?
  • 当然 - 我会在上面的帖子中添加...给我 2 分钟。
  • @StriplingWarrior - 刚刚添加了生成的 HTML。 - 忽略 - 我已经添加了 foreach 循环!!! 2分钟...

标签: c# model-view-controller model-binding


【解决方案1】:

首先,如果您希望在控制器操作中接收多个CustomOrderLines,您将需要获取项目列表。在这种情况下,使用Cart 似乎更合适,它上面有一个CustomOrderLines 列表:

[HttpPost]
public ActionResult UpdateCart(Cart cart)
{
    //add code here
    return XXX;
}

MVC 模型绑定从如下所示的参数填充列表:

cart.OrderLines[0].ItemId = 123
cart.OrderLines[0].Qty = 1
cart.OrderLines[1].ItemId = 456
cart.OrderLines[1].Qty = 2

因此,为了使您的 HTML 输入的 name 属性与此模式匹配,需要为 EditorFor 提供一个表达式,以帮助它知道如何构造此名称:

@for (int i=0; i<Model.Cart.OrderLines.Length; i++)
{    
  @Html.EditorFor(m => m.Cart.OrderLines[i])
}  

您会注意到我正在使用EditorFor,因为您似乎在显示您的订单的可编辑版本。如果您这样做,您将希望将显示模板移动到编辑器模板的位置。

【讨论】:

  • 完美 - 让它将整个购物车传递给 Action - 不完全是我想要的,但我完全可以解决这个问题 - 感谢您的帮助。
【解决方案2】:

如果您想保持单行更新,请将您的控制器操作签名更改为:

[HttpPost]
public ActionResult UpdateCart(CustomOrderLine ol)
{
    return XXX;
}

这将匹配DisplayFor(m =&gt; ol) 中呈现的前缀。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 2014-07-10
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    相关资源
    最近更新 更多