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

Имам проблем при опит да предам модел от частичен изглед към контролера за по-нататъшна обработка.

Това е моят контролер:

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

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

Този в моя индексен изглед. което, както виждате, включва частичен изглед _Permissions.

@model WebApp.ViewModels.PermissionsModel
<script>
    $(document).ready(function () {
        $('#AdminTabs').tabs();
    });
</script>
<div id="AdminTabs">
    <ul>
        <li><a href="/bg#tabs-1">Permissions</a></li>
        <li><a href="/bg#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 Partial View ... методът „Permissions“ в контролера „Admin“, който обработва това действие, получава празен модел „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' на само for ... razor няма да разбере, че искам да се завъртя в PermissionCollection, нито да разпознае de var i дефиницията. ActionRoleEntity има гетери и сетери за свойства като това: public string RoleName { get; комплект; }   -  person jmberon    schedule 01.12.2014
comment
идва с брой 0 или идва null @jmberon ??   -  person Ehsan Sajjad    schedule 01.12.2014
comment
Ваше право - не забелязах, че цикълът ви е вътре в елемент <table>. Не виждам никаква причина да не обвърже тези 3 свойства. Но вашата клауза .Where() изглежда странна. Защо бихте визуализирали елементи за ActionRoleEntity, където стойността на hasChanged е невярно, ако след това ще игнорирате всички промени, които потребителят е направил в състоянията на квадратчето за отметка? Накарай ме да мисля, че имаш някакъв 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 . променете го на модел и на двете места.

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 model){} - person jmberon; 02.12.2014