Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top