Search code examples
asp.netasp.net-mvc-3model-binding

MVC3 in situ table update


I'm a bit confused.

I have a pretty standard MVC3 setup: Home Controller/Index method, Strongly typed view to a ViewModel.

My ViewModel is a collection of three generic lists (Schemes, Types, Tables),

TableModel Schemes List TypesList TablesList

Schemes and Types populate dropdowns to act as filters on the third (Tables) collection which populates a HTML table via a @foreach loop

I populate these via a call to Home/Index (no arguments). This works fine. Now I want to mark a number of rows from the TablesList collection for deletion by checking a checkbox and then, on clicking Submit, I want the deletion to be actioned via a Post and the table contents to be refreshed with the remaining tables back into the same place (replacing the existing HTML table

In my Index View I have this section:

@using (Html.BeginForm("DeleteTables", "Home"))
{
    @Html.Hidden("tableList", @Model.TablesList)
    <input id="deleteButton" type="submit"  />
}

in my HomeController I have a POST method as follows

[HttpPost]
public ActionResult DeleteTables(List<ViewModel.ITableInformation> tableList)
{
    var deleteableTableIds = from t in tableList
                             where t.DeleteTable
                             select t.TableId;

    this.tableModel.DeleteTablesById(deleteableTableIds.ToList());


    .... execute a db call to get remaining tables and return a PartialView or JSON              
    }

Problem is I'm expecting the tableList argument to this function to contain my model but it's empty.

Any idea what I'm doing wrong - pretty new to this I'm afraid.

Thanks


Solution

  • The hidden can't take a complex object; what you would need to do is deserialize each object and store it in the hidden as a string, something like:

    @{
      var tableIDs = "";
    
      foreach (var i in Model.TablesList) {
         tableIDs = //serialized object in proper format
      }
    }
    
    @Html.Hidden("tableList", @tableIDs)
    

    From the server, you can create the objects through a custom model binder, or accept an input of type string, and deserialize the collection.