Не все значения в форме MVC публикуются

Небольшая помощь или совет, если кто-нибудь из вас может? У меня есть форма MVC (на самом деле это контроллер формы / поверхности Umbraco, но я не знаю, какое это имеет отношение к этому), модель для которой содержит список объектов, используемых для создания флажков с использованием вспомогательных методов HTML; см. следующий пост о том, как я их отображаю и получаю в дочернем действии: /questions/30832965/aspnet-mvc-checkboxlist-iz-modeli-so-svojstvom-list/30832976#30832976

Кажется, что все работает хорошо, за исключением того, что, хотя все флажки выставляются при отправке, не все выбираются моделью, полученной методом ActionResult в моем контроллере. Я просмотрел опубликованные данные, используя сетевые инструменты в chrome, и все, кажется, в порядке... (все флажки, по-видимому, отправляются обратно в одном и том же формате), поэтому вопрос на миллион долларов заключается в том, что может помешать некоторые значения от того, чтобы быть подобранным в модели?

Вот фрагмент моей формы, отображающий чекбоксы, поскольку остальные не должны быть релевантными (да, в реальной вещи есть кнопка "Отправить"):

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

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

Результат действия:

[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 бренда, кажется, она только когда-либо достигла 'HandleDealerMemberPreferencesAccountUpdate' с 12.

Любая помощь оценена (я надеюсь, что это что-то простое, где я поскользнулся)..

отметка

1 ответ

Решение

Хорошо, это оказалось проблемой с моими данными, что не должно было быть возможным.

Комментарий Стивена Мюке выше был действительно правильным

У вас есть блок if внутри вашего цикла for. Если это когда-либо оценивается как ложное, это означает, что вы пропускаете "индексатор" и привязка не будет выполнена, когда вы отправите запрос. по умолчанию индексаторы коллекции должны начинаться с нуля и быть последовательными. Хотя вы можете добавить входные данные для индексатора, чтобы сделать эту работу, вы должны использовать модель представления, которая содержит только те объекты, которые вам нужны в представлении.

По сути, у одного из моих брендов не было подразделения, связанного с ним, и поэтому он сломал решение, не будучи должным образом отправлен на контроллер. Код нуждается в рефакторинге, так что это невозможно, хотя я внес изменения в CMS, чтобы предотвратить повторение этого.

Надеюсь, это поможет кому-то еще, спасибо всем за указатели.

Другие вопросы по тегам