简体   繁体   English

并非以MVC形式发布的所有值

[英]Not all values in MVC form being posted

A little help or advice if any of you can? 你们有什么帮助或建议吗? I have an MVC form (it's actually an Umbraco form/surface controller, but I don't know that that has any bearing on this), the model for which contains a list of objects being used to generate check-boxes using HTML helper methods; 我有一个MVC表单(实际上是Umbraco表单/表面控制器,但我不知道这与它有任何关系),该模型的模型包含一个对象列表,该对象列表用于使用HTML帮助器方法生成复选框; see the following post for how I am rendering these and receiving them in my child action: https://stackoverflow.com/a/20687405/1285676 请参阅以下帖子,了解我如何在我的子动作中呈现并接收它们: https : //stackoverflow.com/a/20687405/1285676

All appears to be working well, except that although all check-boxes are being posted on submit, not all are being picked up by the model received by the ActionResult method in my controller. 尽管所有复选框都在提交时发布,但是所有控件似乎都运行良好,但并不是我的控制器中ActionResult方法接收到的模型拾取了所有复选框。 I have looked at the posted data using the network tools in chrome, and all appears to be ok.. (all check-boxes appear to be being posted back in the same format), so the million dollar question is, what could be preventing some values from being picked up in the model? 我已经使用chrome浏览器使用网络工具查看了发布的数据,并且看起来一切正常。(所有复选框似乎都以相同的格式发布了),所以百万美元的问题是,这可能会阻止从模型中获取一些价值?

Here's a snipet of my form rendering the check-boxes, cut down as the rest should not be relevant (yes there is a submit button in the real thing..): 这是我的表单的摘要,呈现了复选框,由于其余部分不相关,因此被缩减了(是的,在真实的东西中有一个提交按钮。):

@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>
        }
    }
}

Slightly cut down version of the model: 略减模型的版本:

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);
        }
    }
}

BrandVM: BrandVM:

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; }
}

The ActionResult: 动作结果:

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

The model should contain 24 Brands, it only ever seems to arrive at 'HandleDealerMemberPreferencesAccountUpdate' with 12. 该模型应包含24个品牌,似乎只有12个品牌才能到达“ HandleDealerMemberPreferencesAccountUpdate”。

Any help appreciated (am hoping it's something simple where I've slipped up).. 任何帮助表示赞赏(我希望这是我滑倒的简单方法)。

Mark 标记

Ok, this turned out to be an issue with my data, that shouldn't have been possible. 好的,事实证明这与我的数据有关,这是不可能的。

Stephen Muecke's comment above was indeed correct 斯蒂芬·穆克(Stephen Muecke)的上述评论确实是正确的

You have an if block inside your for loop. 您的for循环中有一个if块。 If that ever evaluates to false it means you skip an 'indexer' and binding will fail when you submit. 如果该评估结果为false,则意味着您跳过了“索引器”,并且在提交时绑定将失败。 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. 虽然可以为索引器添加输入以完成此工作,但您应该使用仅包含视图中所需对象的视图模型。

Essentially, one of my brands didn't have a division associated with it and so it broke the solution by not being posted to the controller correctly. 本质上,我的一个品牌没有与之相关的部门,因此它由于未正确发布到控制器而破坏了解决方案。 The code does need refactoring so that this isn't possible, though I have made changes in the CMS to prevent this from happening again. 尽管确实在CMS中进行了更改,以防止再次发生这种情况,但是代码确实需要进行重构,以使这不可能实现。

Hopefully this will help someone else, thanks all for the pointers. 希望这会对其他人有所帮助,谢谢大家的指点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM