Отправка одного экземпляра массива в контроллер - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть модель вида:

public class OrganisationViewModel
{
    public string OrganisationName { get; set; }
    public List<BranchViewModel> Branches { get; set; }
    // more properties...
}

public class BranchViewModel
{
    public string BranchName { get; set; }
    // more properties...
}

Вот как выглядит страница организации:

enter image description here

Что Я хочу добиться того, чтобы пользователь мог обновить один BranchViewModel, поэтому я создал модал для каждой ветви, и когда пользователь нажмет на ссылку «Изменить ветку», откроется модальное окно:

@for (int i = 0; i < Model.BranchViewModels.Count(); i++)
{
    var branchModalId = OrganisationHelper.GetBranchModalId(Model.BranchViewModels[i].BranchId);

    <div class="modal fade" id="@branchModalId" tabindex="-1" role="dialog" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered" role="document">
            <div class="modal-content">
                <form action="/organisation/updateBranch" method="post" role="form">
                    <div class="modal-body">
                        @Html.AntiForgeryToken()
                        <div class="form">
                            <div class="form-group">
                                @Html.LabelFor(m => Model.BranchViewModels[i].BranchName, htmlAttributes: new { @class = "", @maxlength = GlobalConstants.MaxLengthForLongName })
                                @Html.TextBoxFor(m => Model.BranchViewModels[i].BranchName, new { @class = "form-control input-text" })
                                @Html.ValidationMessageFor(m => Model.BranchViewModels[i].BranchName, "", new { @class = "text-danger" })
                            </div>

                            @*more properties...*@
                        </div>

                    </div>
                    <div class="modal-footer">
                        <input type="button" value="Cancel" class="btn btn-secondary-grey" data-dismiss="modal" />
                        <input type="submit" class="btn btn-primary-action" value="Save" />
                    </div>
                </form>
            </div>
        </div>
    </div>
}

enter image description here

Теперь проблема в том, что, поскольку ветви принадлежат массиву, входные данные на странице генерируются как массив, так что-то вроде этого:

<input class="form-control input-text" data-val="true" id="BranchViewModels_0__BranchName" name="BranchViewModels[0].BranchName" readonly="readonly" type="text" value="35671900246">

Поэтому, когда я отправляю изменения в ветку, значения передаются в контроллер как List, так что этот контроллер будет принимать список из одной ветви:

public ActionResult UpdateBranch(List<BranchViewModel> branchViewModel)
{
}

То, чего я хочу достичь, - это быть возможность передать одну ветвь контроллеру, поэтому я хочу, чтобы сигнатура контроллера была такой:

public ActionResult UpdateBranch(BranchViewModel branchViewModel)
{
}

Но мне нужно, чтобы ветвь отображалась как массив в HTML, в противном случае я получит дублированные идентификаторы ввода ... каков наилучший способ добиться этого?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020

ASP. NET MVC Сериализация работает с html именами элементов. Индексаторы будут иметь html имен элементов с _i__ (где i - индекс ветви в этой коллекции), когда вы создадите их через для l oop. Таким образом, вместо использования индексаторов (обращаясь к Model.BranchViewModels [i] через l oop), вы можете попробовать использовать foreach.

@{
    var idx = 0;
}
@foreach (var branch in Model.BranchViewModels)
{
    var branchModalId = OrganisationHelper.GetBranchModalId(branch.BranchId);

    <div class="modal fade" id="@branchModalId" tabindex="-1" role="dialog" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered" role="document">
            <div class="modal-content">
                <form action="/organisation/updateBranch" method="post" role="form">
                    <div class="modal-body">
                        @Html.AntiForgeryToken()
                        <div class="form">
                            <div class="form-group">
                                @Html.LabelFor(m => branch.BranchName, htmlAttributes: new { @class = "", @maxlength = GlobalConstants.MaxLengthForLongName })
                                @Html.TextBoxFor(m => branch.BranchName, new { @class = "form-control input-text", @id= Model.BranchViewModels[idx].BranchName})
                                @Html.ValidationMessageFor(m => branch.BranchName, "", new { @class = "text-danger" })
                            </div>

                            @*more properties...*@
                        </div>

                    </div>
                    <div class="modal-footer">
                        <input type="button" value="Cancel" class="btn btn-secondary-grey" data-dismiss="modal" />
                        <input type="submit" class="btn btn-primary-action" value="Save" />
                    </div>
                </form>
            </div>
        </div>
    </div>
    idx++;
}
0 голосов
/ 21 февраля 2020

Можете ли вы попробовать вместо использования stati c @HTML.LabelFor и @HTML.TextBoxFor, вы можете написать html вручную с помощью тегов <input> и указать имя поля ввода. Таким образом, у него не будет индекса.

<input name="BranchViewModel.BranchId" type="hidden" value="Model.BranchViewModels[i].BranchId" />
<input name="BranchViewModel.BranchName" max="@GlobalConstants.MaxLenghForName" value="Model.BranchViewModels[i].BranchName" />

Полный модальный код;

@for (int i = 0; i < Model.BranchViewModels.Count(); i++)
{
    var branchModalId = OrganisationHelper.GetBranchModalId(Model.BranchViewModels[i].BranchId);

    <div class="modal fade" id="@branchModalId" tabindex="-1" role="dialog" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered" role="document">
            <div class="modal-content">
                <form action="/organisation/updateBranch" method="post" role="form">
                    <div class="modal-body">
                        @Html.AntiForgeryToken()
                        <div class="form">
                            <div class="form-group">
                                <label>Model.BranchViewModels[i].BranchName</label>
                                <input name="BranchViewModel.BranchId" type="hidden"value="Model.BranchViewModels[i].BranchId" />
                                <input name="BranchViewModel.BranchName" max="@GlobalConstants.MaxLenghForName" value="Model.BranchViewModels[i].BranchName" />
                            </div>

                            @*more properties...*@
                        </div>

                    </div>
                    <div class="modal-footer">
                        <input type="button" value="Cancel" class="btn btn-secondary-grey" data-dismiss="modal" />
                        <input type="submit" class="btn btn-primary-action" value="Save" />
                    </div>
                </form>
            </div>
        </div>
    </div>
}
...