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?

7
  • make sure you are posting to this page by using a <form method="POST"> Commented May 15, 2016 at 12:18
  • Tried kind of everything, at the moment it is: @using (Html.BeginForm()) Commented May 15, 2016 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 Commented May 15, 2016 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 Commented May 15, 2016 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 Commented May 15, 2016 at 12:41

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

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.
You can have complex model as a parameter, there is no need for changing it to List<T>. Built-in model binder will handle nested properties properly if your view generates proper input names.
The use of a foreach loop instead of a for loop was the thing that gave me issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.