并非 MVC 表单中的所有值都被发布

Not all values in MVC form being posted

如果可以,请提供一点帮助或建议? 我有一个 MVC 表单(它实际上是一个 Umbraco form/surface 控制器,但我不知道这与此有任何关系),该模型包含一个对象列表,用于使用 HTML 辅助方法;请参阅以下 post,了解我如何呈现这些内容并在我的子操作中接收它们:

一切似乎都运行良好,除了尽管所有复选框都在提交时被 posted,但并非所有复选框都被我的控制器中的 ActionResult 方法接收的模型选中。我已经使用 chrome 中的网络工具查看了 posted 数据,一切似乎都正常..(所有复选框似乎都被 posted 返回到相同的位置格式),所以百万美元的问题是,是什么阻止了模型中获取某些值?

这是呈现复选框的表单片段,由于其余部分不相关(是的,在真实的东西中有一个提交按钮..):

@model MemberPreferencesVM
@using (Html.BeginUmbracoForm<MemberAccountSurfaceController>("HandleDealerMemberPreferencesAccountUpdate", FormMethod.Post, new { @class = "", @id = "dealer-member-account-preferences-form" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    @for (var j = 0; j < Model.Brands.Count; j++)
    {
        if (Model.Brands[j].Division == Model.Divisions[i].Id.ToString())
        {
            var divisionSelected = Model.Divisions.Any(x => x.Id.ToString() == Model.Brands[j].Division) ? Model.Divisions.FirstOrDefault(x => x.Id.ToString() == Model.Brands[j].Division).Checked : false;
            var checkboxAttr = new Dictionary<string, object> { { "class", "styled" }, { "data-division", Model.Brands[j].Division } };
            var brandSelected = Model.Brands[j].Checked;

            <div class="col-xs-4">
                <label class="option @if (divisionSelected && brandSelected){<text>active</text>}">
                    <img src="@(Model.Brands[j].LogoUrl)" class="center-block" alt="@(Model.Brands[j].Name)" />
                    <span class="checkbox">
                        @Html.HiddenFor(model => model.Brands[j].Id)
                        @Html.HiddenFor(model => model.Brands[j].Name)
                        @Html.CheckBoxFor(model => model.Brands[j].Checked, checkboxAttr)
                    </span>
                </label>
            </div>
        }
    }
}

模型略有缩减版本:

public class MemberPreferencesVM: IValidatableObject
{
    public MemberPreferencesVM()
    {
        init();
    }
    private void init()
    {
        Divisions = [Logic to fetch divisions];
        Brands = [Logic to fetch brands];
    }
    public IList<DivisionVM> Divisions { get; set; }
    public IList<BrandVM> Brands { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var pDivisions = new[] { "Divisions" };
        var pBrands = new[] { "Brands" };
        if (!Divisions.Any(x => x.Checked))
        {
            yield return new ValidationResult("Select at least 1 division to view by default", pDivisions);
        }
        if (!Brands.Any(x => x.Checked))
        {
            yield return new ValidationResult("Select at least 1 brand to view by default", pBrands);
        }
    }
}

品牌虚拟机:

public class BrandVM
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string LogoUrl { get; set; }
    public bool Checked { get; set; }
    public string Division { get; set; }
}

操作结果:

[ValidateAntiForgeryToken]
[ValidateInput(true)]
[HttpPost]
public ActionResult HandleDealerMemberPreferencesAccountUpdate(MemberPreferencesVM model)
{
    //logic removed as model doesn't arrive will all values so not relevant 
    return CurrentUmbracoPage();
}

该模型应该包含 24 个品牌,它似乎只有 12 个才到达 'HandleDealerMemberPreferencesAccountUpdate'。

任何帮助表示赞赏(我希望这是我滑倒的简单事情)..

马克

好的,这原来是我的数据有问题,这不应该是可能的。

Stephen Muecke 的上述评论确实正确

You have an if block inside your for loop. If that ever evaluates to false it means you skip an 'indexer' and binding will fail when you submit. by default, collection indexers must start at zero and be consecutive. While you can add an input for the indexer to make this work, you should be using a view model that contains only the objects you need in the view.

基本上,我的一个品牌没有与之关联的部门,因此它没有正确发布到控制器,从而破坏了解决方案。代码确实需要重构,所以这是不可能的,尽管我已经在 CMS 中进行了更改以防止这种情况再次发生。

希望这对其他人有所帮助,感谢大家的指点。