Vivendi
Vivendi

Reputation: 21057

Posting array of form fields with C# MVC BeginForm

I have a .NET MVC4 web application where I'm using jquery datatables to create a grid.

That grid holds about 100 users, but it only shows 5 users per page. In front of every user name I have a checkbox. I can select users from my grid and press the delete button to delete those users.

My table is build like this (simply put):

<table class="datatables">
    <tbody>
        <tr>
            <td><input type="checkbox" name="user[0].Delete" /></td>
            <td><input type="hidden" name="user[0].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[1].Delete" /></td>
            <td><input type="hidden" name="user[1].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[2].Delete" /></td>
            <td><input type="hidden" name="user[2].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[3].Delete" /></td>
            <td><input type="hidden" name="user[3].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[4].Delete" /></td>
            <td><input type="hidden" name="user[4].Username" /></td>
        </tr>
    </tbody>
</table>

Right now I can select the first two checkboxes and hit a Delete button to delete the selected records. The works fine. This will call an ActionResult which looks like this:

public ActionResult Delete(UserDeleteModel[] users)
{
    // delete records code
}

*BUT, * when I navigate to the 2nd page in the datatables grid, then my table HTML will look like this:

<table class="datatables">
    <tbody>
        <tr>
            <td><input type="checkbox" name="user[5].Delete" /></td>
            <td><input type="hidden" name="user[5].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[6].Delete" /></td>
            <td><input type="hidden" name="user[6].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[7].Delete" /></td>
            <td><input type="hidden" name="user[7].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[8].Delete" /></td>
            <td><input type="hidden" name="user[8].Username" /></td>
        </tr>
        <tr>
            <td><input type="checkbox" name="user[9].Delete" /></td>
            <td><input type="hidden" name="user[9].Username" /></td>
        </tr>
    </tbody>
</table>

So the input fields start counting from 5. Which makes sense of course.

But when I select a user and hit the Delete button then I do see that the browsers POSTS all the input fields and their values, but the ActionResult gives me an empty UserDeleteModel[] list.

The reason why UserDeleteModel[] list is NULL is because the form fields in the table grid don't start counting from 0 on page two. It starts from 5 on the second page.

For some reason .NET MUST have fields that start from 0 counting upwards in order. If it starts from any other number then the posted fields aren't mapped to my ViewModel in the controller.

I do see the form values in the Request.Form object. But for reason it's not being mapped.

This is a problematic bug of course. Anyone any idea how to solve this issue?

Upvotes: 2

Views: 2503

Answers (1)

Floremin
Floremin

Reputation: 4089

The problem you are experiencing is in how ASP.NET MVC binds collections. You are posting a non-sequential collection (i.e. index does not start with at 0), so the default MVC binder does not know how to resolve.

Take a look at the following answer:

Non-sequential collection binding

Other solution would be to create your own binder, depending on your needs.

Upvotes: 3

Related Questions