asp.net Разместите форму с моделью представления в методе действия контроллера

У меня есть довольно сложная форма, которую мне нужно опубликовать на моем контроллере MVC.

Вот модель представления, которую я изначально передаю в представление при создании:

public class EditViewModel
{
    public Service service { get; set; }
    public bool sms { get; set; }
    public bool email { get; set; }
    public string userId { get; set; }
}

Вот мой вид (упрощенный):

@model IList<Service_Monitor_Web_Interface.Models.ViewModels.EditViewModel>
@{
  ViewBag.Title = "Configure User Notifications";
  Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm("Edit", "Users", FormMethod.Post, new { @class = "stdform stdform2", role = "form" }))
{
@Html.AntiForgeryToken()
<hr />

<p>
    <label><u> Service:</u> </label>
    <span class="field">
        <u>Notification Methods:</u>
    </span>
</p>


for (int i = 0; i < Model.Count; i++)
{
    <p>
        <label>@Model[i].service.Name</label>
        <span class="field">
            @Html.CheckBoxFor(model => model[i].sms)
            SMS &nbsp;&nbsp;
            @Html.CheckBoxFor(model => model[i].email)
            Email &nbsp;&nbsp;
        </span>
    </p>
}
<br clear="all" /><br />

<p class="stdformbutton">
    <button class="submit radius2">Save</button>
    <input type="reset" class="reset radius2" value="Reset Form" />
</p>
}

А вот мой метод Action в моем контроллере:

    //
    // POST: /Users/Edit
    [HttpPost]
    public ActionResult Edit(IList<EditViewModel> viewModel)
    {
        return View(viewModel);
    }

Как я могу связать свою модель представления при ее получении на контроллере? В настоящее время, когда я отлаживаю, метод действия получает ViewModel, который выглядит так:

введите здесь описание изображения

Как я могу сделать так, чтобы сервис и идентификатор пользователя не были нулевыми?


person Zapnologica    schedule 25.02.2014    source источник


Ответы (1)


Обратите внимание, что в лямбда-выражениях ваших помощников, скажем, в model => service.sms правая часть (service.sms) формально не является производной от левой части (model). Это приводит к тому, что все атрибуты name результирующих входных данных будут одинаковыми, и вы получите параметры запроса, которые вы не ожидали.

Стандартной практикой является использование for вместо foreach в случаях цикла. Таким образом, атрибуты имени для результирующего html генерируются правильно:

for(int i=0; i<Model.Count; i++)
{
    <p>
        <label>@Model[i].service.Name</label>
        <span class="field">                
            @Html.CheckBoxFor(model => model[i].sms)
            SMS &nbsp;&nbsp;               
            @Html.CheckBoxFor(model => model[i].email)
            Email &nbsp;&nbsp;
        </span>
    </p>
}

Обратите внимание, что для этого требуется, чтобы Model относился к типу, реализующему IList, а не IEnumerable.

Обновить. Для других значений, для которых нет никакого пользовательского интерфейса, вы можете использовать скрытые поля, чтобы они не были видны пользователю и тем не менее отправлялись на сервер:

<label>@Model[i].service.Name</label>
<span class="field">                
    @Html.CheckBoxFor(model => model[i].sms)
    SMS &nbsp;&nbsp;               
    @Html.CheckBoxFor(model => model[i].email)
    Email &nbsp;&nbsp;
    @Html.HiddenFor(mode => model[i].userId)
    @Html.HiddenFor(mode => model[i].service.Name)
    ...other field of service you want to be posted...
</span>
person Andrei    schedule 25.02.2014
comment
Ему не нравится ваше решение. !st ошибка находится в цикле for, он говорит, что Operator > cannot be applied to operands of type int and method group, а затем во-вторых, в флажке Cannot apply indexing with [] to an expression of type IEnumerable - person Zapnologica; 25.02.2014
comment
@Zapnologica, ах да, забыл упомянуть - вам нужно, чтобы ваша модель была типа IList, чтобы это работало. так как IEnumerable является более широким интерфейсом и не поддерживает индексацию. По сути, вы можете просто вызвать ToList() при передаче модели в представление и настроить тип представления. - person Andrei; 25.02.2014
comment
Должен ли я тогда получать ViewModel IList‹EditViewModel› в моем методе действия? - person Zapnologica; 25.02.2014
comment
@Zapnologica, нет, должно работать без изменения сигнатуры постприемного действия - person Andrei; 25.02.2014
comment
ОМВ Ты потрясающий. Большое спасибо. Вы действительно помогли, и вы сэкономили мне часы. Есть ли причина, по которой вы должны использовать цикл for, а не foreach? - person Zapnologica; 25.02.2014
comment
@Zapnologica, рад, что помогло. Причину я попытался кратко объяснить в начале ответа. Возможно, вы захотите проверить полученный html на наличие циклов for и foreach, чтобы понять, что происходит. - person Andrei; 25.02.2014