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

У меня проблема с попыткой передать модель из частичного представления в контроллер для дальнейшей обработки.

Это мой контроллер:

public ActionResult Index()
{
    IList<ActionRoleEntity> permissionCollection = new SecurityManager().GetPermissionCollection();

    var model = new PermissionsModel
    {
        PermissionCollection = permissionCollection
    };
    return View(model);
}    

Это в моем представлении Index. который, как вы видите, включает в себя частичное представление _Permissions.

@model WebApp.ViewModels.PermissionsModel
<script>
    $(document).ready(function () {
        $('#AdminTabs').tabs();
    });
</script>
<div id="AdminTabs">
    <ul>
        <li><a href="#tabs-1">Permissions</a></li>
        <li><a href="#tabs-2">Insights</a></li>        
    </ul>    
    <div id="tabs-1">        
        @{ Html.RenderPartial("_Permissions"); }
    </div>  
    <div id="tabs-2">
        <p>            
        </p>
    </div>
</div>

А это мое частичное мнение:

@model WebApp.ViewModels.PermissionsModel
@using (Html.BeginForm("Permissions", "Admin", FormMethod.Post))
{
    <table id="example" class="display">
    <thead>
        <tr>
            <th>Role</th>
            <th>Workflow</th>
            <th>Stage</th>
            <th>Action</th>            
            <th>Read</th>
            <th>Update</th>
            <th></th>
        </tr>
    </thead>    
    <tbody>
        @for (var i = 0; i < Model.PermissionCollection.Count; i++)
        {
            <tr>
                <td>@Html.DisplayTextFor(m => m.PermissionCollection[i].RoleName)</td>
                <td>@Html.DisplayTextFor(m => m.PermissionCollection[i].Workflow)</td>
                <td>@Html.DisplayTextFor(m => m.PermissionCollection[i].StageName)</td>
                <td>@Html.DisplayTextFor(m => m.PermissionCollection[i].ActionName)</td>                
                <td>@Html.CheckBoxFor(m => m.PermissionCollection[i].Get)</td>
                <td>@Html.CheckBoxFor(m => m.PermissionCollection[i].Post)</td>
                <td>@Html.HiddenFor(m => m.PermissionCollection[i].hasChanged)</td>
            </tr>
        }
    </tbody>
    </table>
    <input type="submit" id="btnSubmit" name="btnSubmit" value="Save" />    
}

Модель корректно заполняется для контроллера, а html-код в частичном представлении отображается без проблем. Однако, когда я отправляю форму, нажимая кнопку отправки в частичном представлении _permissions... метод «Разрешения» в контроллере «Администратор», который обрабатывает это действие, получает пустую модель «PermissionModel».

Это код для этого действия:

[HttpPost]
public ActionResult Permissions(PermissionsModel permissionsModel)
{
    IList<ActionRoleEntity> actionRoleEntity = permissionsModel.PermissionCollection.Where(m => m.hasChanged == true).ToList<vw_ActionRoleEntity>();

    // Save changed permission to database

    return View("Index");
}

И, наконец, вот как была закодирована модель разрешений:

public class PermissionsModel
{        
    public IList<ActionRoleEntity> PermissionCollection { get; set; }
}

Javascript для обновления свойства hasChanged объекта ActionRoelEntity.

$("#example input[type='checkbox'").change(function () {
        var arrayCheckboxId = $(this).attr('id').split('_');
        var index = arrayCheckboxId[2]; // Gets specific row Id.
        $('#PermissionCollection_' + index + '__hasChanged').val(true);
    });

Если вы видите что-то, что я могу упустить, пожалуйста, посоветуйте.


person jmberon    schedule 01.12.2014    source источник
comment
Вы поместили оператор @model WebApp.ViewModels.PermissionsModel поверх своего частичного представления? похоже у вас частичный вид не сильно типичный для модели   -  person Ehsan Sajjad    schedule 01.12.2014
comment
Покажите код для модели Permissions. Есть ли у PermissionCollection и его свойств сеттеры?   -  person    schedule 01.12.2014
comment
@EhsanSaijad - И основной вид, и частичный вид строго типизированы - я пропустил строку, но сейчас включил. Спасибо.   -  person jmberon    schedule 01.12.2014
comment
@StephenMuecke Я включил код для PermissionsModel по запросу. Спасибо.   -  person jmberon    schedule 01.12.2014
comment
Вы уверены, что это настоящий код @for(.., который выдаст ошибку синтаксического анализатора? Это должно быть просто for(.... Если свойства ActionRoleEntity имеют сеттеры, то они должны быть привязаны к коллекции (должны быть заполнены Get, Post` и hasChanged).   -  person    schedule 01.12.2014
comment
Привет @StephenMuecke. Конечно, это настоящий код. Если изменить '@for' на просто для... бритва не узнает, что я хочу зациклиться в PermissionCollection, и не распознает определение de var i. ActionRoleEntity имеет геттеры и сеттеры для таких свойств: public string RoleName { get; набор; }   -  person jmberon    schedule 01.12.2014
comment
он приходит с Count of 0 или приходит null @jmberon ??   -  person Ehsan Sajjad    schedule 01.12.2014
comment
Вы правы - не заметили, что ваш цикл находится внутри элемента <table>. Не вижу причин, по которым он не связывал бы эти 3 свойства. Но ваш пункт .Where() кажется странным. Зачем вам отображать элементы для ActionRoleEntity, где значение hasChanged равно false, если вы собираетесь игнорировать любые изменения, внесенные пользователем в состояния флажков? Заставьте меня думать, что вы задействовали какой-то javascript?   -  person    schedule 01.12.2014
comment
Да, @StephenMuecke использует Javascript. Это форма администратора для назначения/отказа разрешений. Когда флажок (Чтение, Обновление) в любой строке изменяется, с помощью Javascript я помечаю свойство hasChanged как true. В контроллере я фильтрую только те строки, на которые влияют изменения пользователя, поэтому я просто обновляю в базе данных необходимые разрешения. Однако PermissionModel имеет PermissionCollection = null, когда я получаю его в методе Permissions моего контроллера. Я ожидаю ту же модель, которую я установил в методе get контроллера, плюс любые варианты флажков в форме.   -  person jmberon    schedule 01.12.2014
comment
@EhsanSajjad Свойство PermissionCollection модели PermissionModel становится нулевым.   -  person jmberon    schedule 01.12.2014
comment
Делает ли javascript что-либо, кроме простого изменения скрытого входного значения (с true на false или наоборот)? Например, вы не отключаете какие-либо элементы управления?   -  person    schedule 01.12.2014
comment
@StephenMuecke Я включил определение Javascript. В основном просто измените свойство hasChanged на true, если какое-либо изменение было применено к любому флажку.   -  person jmberon    schedule 01.12.2014
comment
Есть несколько проблем с вашим сценарием, и это ничего не изменит, хотя я не думаю, что это объясняет, почему PermissionCollection является null.   -  person    schedule 01.12.2014
comment
Кстати, это должно быть что-то вроде $('#example input[type="checkbox"]').change(function () { $(this).closest('tr').find('input[type="hidden"]').val("True"); }) У вас нет входных данных с id="APS_PermissionCollection..." (или, если вы это сделаете, ничего не будет привязано, потому что ваша модель не содержит свойства с именем APS)   -  person    schedule 01.12.2014
comment
@StephenMuecke Спасибо за совет, приятель. Очень ценю это.   -  person jmberon    schedule 01.12.2014
comment
Шаг 1) В Chrome нажмите F12 прямо перед публикацией. Нажмите на вкладку сети, а затем нажмите кнопку, чтобы отправить сообщение. Шаг 2) Найдите данные формы, переданные обратно контроллеру. Сравните пары "имя-значение" с известным вам макетом модели разрешений. MVC всегда будет создавать нулевой экземпляр модели при входе в контроллер (сразу после проверки). Затем он пытается сопоставить имена данных формы с именами свойств класса модели. Если вы не видите, шансы данных высоки, это сообщение не возвращает пары значений имени собственного.   -  person JWP    schedule 01.12.2014


Ответы (1)


Посмотрите, как называется ваша модель в методе Post и в представлении. Я вижу, что вы назвали модель в представлении @model WebApp.ViewModels.PermissionsModel, а в ваших лямбда-назначениях модель — m, а в вашем методе публикации — permissionsModel. . измените его на model в обоих местах.

person Pierro    schedule 02.12.2014
comment
Большое спасибо, приятель. Это решило проблему, у меня кончились волосы из-за того, что я их выдергивал. Я заменил ‹td›@Html.DisplayTextFor(m =› m.PermissionCollection[i].RoleName)‹/td› на ‹td›@Html.DisplayTextFor(model =› model.PermissionCollection[i].RoleName)‹/ td› и метод в контроллере [HttpPost] public ActionResult Permissions (модель PermissionsModel) {} - person jmberon; 02.12.2014