ASP.Net MVC索引输入没有绑定到POST上的模型

时间:2014-08-05 06:55:22

标签: c# asp.net razor asp.net-mvc-5.1

我正在尝试使用以下内容将数据发布回我的控制器,但模型列表始终返回为null。

我已经检查了渲染的HTML,它对我来说似乎有效,但也许我错过了一些东西。从来没有这样做过,我想如果输入与模型匹配,那么它会自动绑定。

Razor查看

    @for (int i = 0; i < Model.Addons.Count; i++)
{
    if (Model.Addons[i].AddonType == AddonType.Bacon)
    {
        <div>
            @Html.HiddenFor(x => Model.Addons[i].Id)
            @Html.TextBoxFor(x => Model.Addons[i].Quantity, new { @style = "width: 40px", @class = "form-control calculated", data_price = Model.Addons[i].Price })
            @Model.Addons[i].Name
            @(" ($")@Model.Addons[i].Price@(")")
        </div><br />
    }
}

结果HTML

    <div class="form-group" id="FoodPlatter">
                <input class="form-control calculated" data-price="30.00" data-val="true" data-val-number="The field Quantity must be a number." data-val-required="The Quantity field is required." id="Addons_32__Quantity" name="Addons[32].Quantity" style="width: 40px" type="text" value="0">
<input class="form-control calculated" data-price="21.00" data-val="true" data-val-number="The field Quantity must be a number." data-val-required="The Quantity field is required." id="Addons_33__Quantity" name="Addons[33].Quantity" style="width: 40px" type="text" value="0">
<input class="form-control calculated" data-price="30.00" data-val="true" data-val-number="The field Quantity must be a number." data-val-required="The Quantity field is required." id="Addons_34__Quantity" name="Addons[34].Quantity" style="width: 40px" type="text" value="0">
    </div>

模型

public class BaconOrderModel {
        public List<Addon> Addons { get; set; }
}

public class Addon
{
    public int Id { get; set; }
    public AddonType AddonType { get; set; } // ENUM
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
    public bool IsSelected { get; set; }
}

控制器

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(BaconOrderModel model)
{
    var baconOrder = new BaconOrder();
    foreach (var addon in model.Addons)
    {
        if (addon.IsSelected)
        {
            baconOrder.Addons.Add(new Addon
            {
                AddonId = addon.Id,
                Quantity = addon.Quantity
            });
        }
    }

    _baconOrderService.Add(baconOrder);
    return RedirectToAction("Index");
}

3 个答案:

答案 0 :(得分:1)

我认为问题是你的索引需要从0开始顺序。因为你在计算i并过滤第一项是在32上编入索引。

索引器需要从0开始并且是顺序的。

答案 1 :(得分:0)

作为对你上次评论的回答:

我认为默认绑定模型的工作方式非常简单。有关模型绑定的介绍,请参阅http://msdn.microsoft.com/en-us/magazine/hh781022.aspx

您可以使用此语法包含/排除属性,这也有助于降低恶意攻击带来的风险。

public ActionResult Edit([Bind(Include = "Name")]Student student)
{
    ...
}

大多数情况下,我使用简单的视图模型,它只携带他们需要的数据。

答案 2 :(得分:0)

经过几次尝试和下面的建议后,我意识到这里的根本问题是索引。挑战在于我的列表按类型(枚举)分组,我通过此枚举类型呈现表单的每个部分。由于我在主列表中获取值的位置,索引不按顺序排列。目前我已将问题修复如下;

在视图中

@{ var index = 0; } 

每个部分(ADDONTYPE)

                @for (int i = 0; i < Model.Addons.Count; i++)
                {
                    if (Model.Addons[i].AddonType == AddonType.BaconStrips) // AddonType is enum.
                    {
                        <div>
                            @Html.Hidden("BaconAddons[" + index + "].Id", Model.Addons[i].Id)
                            @Html.Hidden("BaconAddons[" + index + "].AddonType", Model.Addons[i].AddonType)
                            @Html.Hidden("BaconAddons[" + index + "].Name", Model.Addons[i].Name)
                            @Html.Hidden("BaconAddons[" + index + "].Price", Model.Addons[i].Price)
                            @Html.TextBox("BaconAddons[" + index + "].Quantity", Model.Addons[i].Quantity, new { @style = "width: 40px", @class = "form-control calculated", data_price = Model.Addons[i].Price })
                            @Model.Addons[i].Name
                            @(" ($")@Model.Addons[i].Price@(")")
                        </div><br />
                        { index++; }
                    }
                }

我想知道这是否是最好的方法呢?我试图在我的模型中创建另一个空列表来绑定,但它似乎抛出了“超出范围”异常。我想知道是否有更好的方法吗?