0

My IEnumberable is a null parameter in my action. The binding does not work anymore since I did this:

BEFORE my refactoring

The ListItem.cshtml was inside the List.html

<table id="TeststepsDataTable">
           <tbody>
                @for (int i = 0; i < Model.Count(); i++)
                {

                    <tr>
                        @Html.HiddenFor(item => item[i].UnitId)
                        <td>
                            @Html.EditorFor(item => item[i].Name)
                        </td>                    
                    </tr>
                }
            </tbody>
        </table>

AFTER my refactoring

List.cshtml

<table id="TeststepsDataTable">
           <tbody>
                @for (int i = 0; i < Model.Count(); i++)
                {
                    Html.RenderPartial("ListItem", Model[i]);
                }
            </tbody>
        </table>

ListItem.cshtml

@model ITMS.Web.Models.Teststep.TeststepViewModel

<tr>
    @Html.HiddenFor(item => Model.UnitId)
    <td>
        @Html.EditorFor(item => Model.Name)
    </td>        
</tr>

When my save button in the List.cshtml is clicked this action is triggered:

    [HttpPost]
    public ActionResult Save(IEnumerable<TeststepViewModel> teststepViewModels)
    {
        // do stuff
    }

The teststepViewModels are null because I lost index property stuff like [0].UnitId so the modelbinder can NOT correctly bind the properties.

How can I fix that?

I really want to use the ListItem.cshtml because I want to reuse this code for an Insert/Add operation an empty row.

Elisabeth
  • 20,496
  • 52
  • 200
  • 321

1 Answers1

0

you can use foreach instead of for

    <table id="TeststepsDataTable">
    <tbody>
        @foreach (var item in Model)
        {
            Html.RenderPartial("ListItem", item);

        }        
    </tbody>
</table>

and also you have to bind this way

<tr>
@Html.HiddenFor(item => item.UnitId)
<td>
    @Html.EditorFor(item => item.Name)
</td>        

and, Lock at the expression item=> item.UnitId instead of item=> Model.UnitId

Edit

i added an index property to model

    public class UnitsViewModel
{
    public List<Unit> Units { get; set; }

    public class Unit
    {
        [HiddenInput(DisplayValue = false)]

        public int UnitId { get; set; }

        [DataType(DataType.MultilineText)]
        public string Name { get; set; }

        [DataType(DataType.MultilineText)]
        public string ErrorText { get; set; }

        public int Index { get; set; }
    }
}

in main view i fill index property :

    <table id="TeststepsDataTable">
    <tbody>
        @for (int i = 0; i < Model.Units.Count; i++)
        {
            Model.Units[i].Index = i;
            Html.RenderPartial("ListItem", Model.Units[i]);
        }
    </tbody>
</table>

and in listItem :

@model StackOverflowSample.Models.UnitsViewModel.Unit

@Html.Hidden("Units["+ Model.Index +"].UnitId",Model.UnitId)
<td>
    @Html.TextBox("Units["+ Model.Index +"].Name",Model.Name)
</td>
<td>
    @Html.TextBox("Units["+ Model.Index +"].ErrorText",Model.ErrorText)
</td>

i change Editor to TextBox ,HiddenFor to Hidden.it's Work ;)

Mahdi Farhani
  • 964
  • 1
  • 9
  • 22
  • No I can not use a foreach => http://stackoverflow.com/questions/22866450/model-binding-generic-list-is-null-in-asp-net-mvc – Elisabeth Apr 05 '14 at 20:55
  • can i see your model ? i think you use IEnumerable in your view instead of List.when you use IEnumerable you can't use index and you have getenumerate it, and you can use while instead of for – Mahdi Farhani Apr 05 '14 at 21:13
  • also i think it wont post all your data to action with this structure and always Save(IEnumerable teststepViewModels) will be null, but in your header you see all data passed to action – Mahdi Farhani Apr 05 '14 at 21:14
  • Please have a look at the Update part of my post – Mahdi Farhani Apr 05 '14 at 21:27
  • I am using a List in my List.cshtml because with the IEnumerable the indexing did not work. – Elisabeth Apr 05 '14 at 21:31
  • I did what you say but as I said before the binding does NOT work because its only possible to bind a generic List when you use a for loop not foreach. – Elisabeth Apr 05 '14 at 21:41
  • also if you want MultilineText you can use TextArea – Mahdi Farhani Apr 05 '14 at 22:09
  • Its that messy that I do not want to try it out :P But thank you for the time you invested. – Elisabeth Apr 05 '14 at 22:49