8

I stuck on this issue for a while..

I've created a simple view model:

public class AddTranslationViewModel
{
    public List<ProjectTranslation> ProjectTranslations { get; set; }
    public AddTranslationViewModel()
    {
        ProjectTranslations = new List<ProjectTranslation>();
    }
}

ProjectTranslation class:

public class ProjectTranslation
{
    public int ProjectTranslationId { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Address { get; set; }

    public int LanguageId { get; set; }
    public Language Language { get; set; }

    public int ProjectId { get; set; }
    public Project Project { get; set; }

}

A simple view which uses the AddTranslationViewModel

<table class="table">

    @foreach (var item in Model.ProjectTranslations)
    {
        @Html.HiddenFor(modelItem => item.ProjectTranslationId)
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Language.LanguageCode)
            </td>
            <td>
                @Html.EditorFor(modelItem => item.Title)
            </td>
        </tr>
    }

</table>
<input type="submit" value="Send" />

and finally my POST Method:

    public ViewResult AddTranslation(AddTranslationViewModel projectTranslations)
    {
        if (ModelState.IsValid)
        {
           //...
        }
        return View(projectTranslations);
    }

The idea is very basic, I want to show a list of items where it should be possible to change/edit the values.

However, the model binding is not working, the projectsTranslations param in the HTTPPost-Method AddTranslation is always empty.

What's the mistake here?

mitti
  • 83
  • 1
  • 1
  • 5
  • make sure you are posting to this page by using a
    – adeel41 May 15 '16 at 12:18
  • Tried kind of everything, at the moment it is: @using (Html.BeginForm()) – mitti May 15 '16 at 12:20
  • is the name of Get and Post Action methods is same? and confirm if you used [HttpPost] on your post action method – adeel41 May 15 '16 at 12:24
  • Yes, the names are the same. It's jumping into the post method, 'only' the binding in the object is not set - CONFIRMED, yeah, i use the HttpPost tag – mitti May 15 '16 at 12:28
  • I tried to replicate it but couldn't. viewModel parameter in Post method is not null. Try creating a new project and do as less as possible to replicate the same. You might see the mistake – adeel41 May 15 '16 at 12:41
  • Thanks for your help! Bad title for the topic (I changed it) the viewModel param isn't null, but the list nested in the viewModel object is empty. – mitti May 15 '16 at 12:49
  • Tried to change the foreach in the view to a for loop...same issue – mitti May 15 '16 at 12:50

1 Answers1

13

Binding to a list of object requires creating input field structure with names containing indexes, i.e:

<input type="text" name="YourArrayOrList[0].SomeProperty" value="123" />
<input type="text" name="YourArrayOrList[0].SomeOtherProperty" value="321" />
<input type="text" name="YourArrayOrList[1].SomeProperty" value="123" />
<input type="text" name="YourArrayOrList[1].SomeOtherProperty" value="321" />

Moreover, you need to point the form to the proper Action Method in your Controller using Razor's Html.BeginFrom method (see documentation). In you case it should look like this:

@using(Html.BeginForm("AddTranslation","YourControllerName"))
{
    for (int i=0;i<Model.ProjectTranslations.Count; i++)
    {
        @Html.HiddenFor(model => model.ProjectTranslations[i].ProjectTranslationId)
        <tr>
            <td>
                @Html.DisplayFor(model => model.ProjectTranslations[i].Language.LanguageCode)
            </td>
            <td>
                @Html.EditorFor(model => model.ProjectTranslations[i].Title)
            </td>
        </tr>
    }
}

If your method is not edit, but CREATE method, then obviously your List in model will have 0 elements. In this case, change the stop condition in for loop to desired count.

Keep in mind that this topic was discussed many times before:

ASP.NET MVC bind array in model

ASP.NET MVC - Can't bind array to view model

Community
  • 1
  • 1
Marcin Zablocki
  • 10,171
  • 1
  • 37
  • 47
  • Thank you, already changed the foreach to a for loop. I had to change the ViewModel Parameter in the AddTranslation Method to a List of ProjectTranslation - after that, it worked. – mitti May 15 '16 at 13:24
  • You can have complex model as a parameter, there is no need for changing it to List. Built-in model binder will handle nested properties properly if your view generates proper input names. – Marcin Zablocki May 15 '16 at 13:41
  • The use of a foreach loop instead of a for loop was the thing that gave me issues. – Mötz Dec 12 '16 at 07:51