Viewmodel嵌套复选框没有绑定在帖子上

时间:2016-11-14 00:54:39

标签: asp.net asp.net-mvc model-binding

我有一个包含选项矩阵的订阅表单。表单可以在屏幕截图Subscription table

中看到

我在使用ASP.NET MVC生成适当的ID时出现问题,然后在回发时使用绑定器使用表单选择填充模型。

添加名称位于左侧,当回发时,SubscriptionInputModel.Addons的集合将填充正常。但是,如debug screenshot所示,SubscriptionInputModel.Addons [i] .SubscriptionLevelCombos为null

当前代码正在使用CheckBoxFor,但我也尝试以格式手动生成ID:

@Html.CheckBox("addon[" + a + "].SubscriptionLevelCombo[" + i + "].AddonSelected", addon.SubscriptionLevelCombos[i].AddonSelected)

这两种格式都没有工作,也在调试时进行了实验,但没有运气。我很感激任何想法。最糟糕的情况我认为我需要阅读原始表单集合?

我认为嵌套对象的级别不重要,因为它是html标记名称中的所有对象路径表示法和数组索引?

以下是当前代码的片段,以帮助说明存在的内容。

查看模型

public class SubscriptionInputModel
{
    //other stuff to come
    //....

    //add on's, listed down left of table
    public List<SubscriptionInputAddonModel> Addons;
}

public class SubscriptionInputAddonModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Note { get; set; }
    public List<SubscriptionInputAddonComboModel> SubscriptionLevelCombos { get; set; }
}

public class SubscriptionInputAddonComboModel
{
    public int? Id { get; set; }
    public decimal? AddonCost { get; set; }
    public CostTimeUnitOption? CostTimeUnit { get; set; }
    public bool? IsComplimentaryBySubscriptionLevel { get; set; }
    public string ComboText { get; set; }
    public bool AddonSelected { get; set; }
    public int? AddonId { get; set; }
}

SubscriptionController

[Route("identity/subscription")]
// GET: Subscription
public ActionResult Index()
{
    SubscriptionInputModel model = new SubscriptionInputModel();

    ArrbOneDbContext db = new ArrbOneDbContext();
    List<SubscriptionInputAddonModel> addons = Mapper.Map<Addon[], List<SubscriptionInputAddonModel>>(db.Addons.OrderBy(a => a.OrderPosition).ToArray());
    model.Addons = addons;

    foreach(var addon in model.Addons)
    {
        var addonCombos = db.Database.SqlQuery<SubscriptionInputAddonComboModel>(@"SELECT SLA.Id, AddonCost, CostTimeUnit, IsComplimentaryBySubscriptionLevel, ComboText, AddonId
FROM SubscriptionLevel L
    LEFT OUTER JOIN SubscriptionLevelAddon SLA ON L.Id = SLA.SubscriptionLevelId AND SLA.AddonId = @p0
ORDER BY L.OrderPosition", addon.Id);
        addon.SubscriptionLevelCombos = addonCombos.ToList();
    }
    return View(model);
}

[Route("identity/subscription")]
[ValidateAntiForgeryToken]
[HttpPost]
// POST: Subscription
public ActionResult Index(SubscriptionInputModel model)
{
    ArrbOneDbContext db = new ArrbOneDbContext();
    List<SubscriptionInputAddonModel> addons = Mapper.Map<Addon[], List<SubscriptionInputAddonModel>>(db.Addons.OrderBy(a => a.OrderPosition).ToArray());
    model.Addons = addons;

    //debug breakpoint to inspect returned model values

    return View();
}

Index.cshtml

@model Identity_Server._Code.ViewModel.Subscription.SubscriptionInputModel
@{
    ViewBag.Title = "Subscription";
}

@using (Html.BeginForm("Index", "Subscription", new { signin = Request.QueryString["signin"] }, FormMethod.Post))
{
    @Html.ValidationSummary("Please correct the following errors")
    @Html.AntiForgeryToken()

    ...

    // ADD ONs ----------------------------------------------------------------------------------

    @for (int a = 0; a < Model.Addons.Count; a++)
    {
        var addon = Model.Addons[a];

        <tr>
            <td class="text-left">@addon.Name
                <div class="SubscriptionItemNote">@addon.Note
                        @Html.HiddenFor(m => m.Addons[a].Id)
                </div>
            </td>
            @for (int i = 0; i < addon.SubscriptionLevelCombos.Count; i++)
            {
                <td>
                    @if (addon.SubscriptionLevelCombos[i].Id.HasValue)
                    {
                        if (addon.SubscriptionLevelCombos[i].AddonCost.HasValue && addon.SubscriptionLevelCombos[i].AddonCost.Value > 0)
                        {
                            @Html.Raw("<div>+ " + @addon.SubscriptionLevelCombos[i].AddonCost.Value.ToString("0.##") + " / " + @addon.SubscriptionLevelCombos[i].CostTimeUnit.Value.ToString() + "</div>")
                        }
                        else if (addon.SubscriptionLevelCombos[i].IsComplimentaryBySubscriptionLevel.HasValue && @addon.SubscriptionLevelCombos[i].IsComplimentaryBySubscriptionLevel.Value)
                        {
                            <span class="glyphicon glyphicon-ok"></span>
                        }

                        if (!string.IsNullOrEmpty(addon.SubscriptionLevelCombos[i].ComboText))
                        {
                            <div>@addon.SubscriptionLevelCombos[i].ComboText</div>
                        }

                        if (addon.SubscriptionLevelCombos[i].AddonCost.HasValue && addon.SubscriptionLevelCombos[i].AddonCost.Value > 0)
                        {
                            @Html.HiddenFor(m => m.Addons[a].SubscriptionLevelCombos[i].Id)
                            @Html.CheckBoxFor(m => m.Addons[a].SubscriptionLevelCombos[i].AddonSelected)

                        }
                    }
                </td>
            }
        </tr>
    }

0 个答案:

没有答案