3

I'm writing a view that displays a list of managers. The managers have checkboxes next to their name to select them to be removed from the manager list. I am having problems binding the form submission back to my view model. Here's what the page looks like:

enter image description here

Here's the ViewModel for the page.

public class AddListManagersViewModel
{
    public List<DeleteableManagerViewModel> CurrentManagers;
}

And here's the sub-ViewModel for each of the DeleteableManagers:

public class DeleteableManagerViewModel
{
    public string ExtId { get; set; }
    public string DisplayName { get; set; }

    public bool ToBeDeleted { get; set; }
}

This is the code for the main View:

@model MyApp.UI.ViewModels.Admin.AddListManagersViewModel
<div class="row">
    <div class="span7">
        @using (Html.BeginForm("RemoveManagers","Admin"))
        {
            @Html.AntiForgeryToken()
            <fieldset>
                <legend>System Managers</legend>

                <table class="table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Remove</th>
                        </tr>
                    </thead>

                    <tbody>
                        @Html.EditorFor(model => model.CurrentManagers)
                    </tbody>
                </table>
            </fieldset>
            <div class="form-actions">
                <button type="submit" class="btn btn-primary">Delete Selected</button>
            </div>
        }
    </div>
</div>

And this is the EditorTemplate I've created for DeleteableManagerViewModel:

@model MyApp.UI.ViewModels.Admin.DeleteableManagerViewModel

<tr>
    <td>@Html.DisplayFor(model => model.DisplayName)</td>
    <td>
        @Html.CheckBoxFor(model => model.ToBeDeleted)
        @Html.HiddenFor(model => model.ExtId)
    </td>
</tr>

But when I submit the form to the controller the model comes back null! this is what I want it to do:

[HttpPost]
public virtual RedirectToRouteResult RemoveManagers(AddListManagersViewModel model)
{
    foreach (var man in model.CurrentManagers)
    {
        if (man.ToBeDeleted)
        {
            db.Delete(man.ExtId);
        }           
    }
    return RedirectToAction("AddListManagers");
}

I tried following along this post: CheckBoxList multiple selections: difficulty in model bind back but I must be missing something....

Thanks for your help!

Community
  • 1
  • 1
solidau
  • 4,021
  • 3
  • 24
  • 45
  • 1
    Does Firebug show anything being posted? Have you tried adding Glimpse (which will let you track the binding process)? – Tieson T. Jul 02 '13 at 21:55
  • it appears to be posted properly: __RequestVerificationToken=H7L_Uq6ie_6XAoYFhJQhQe2cuFdJzapaf8ZlgpnEVeUs3kr8kCu7wuVAjZ9ADXzsDZiKmHyqYLkdbVtG7CmSKPqE_upz1eR0Ub0aPxem94Y1&CurrentManagers%5B0%5D.ToBeDeleted=true&CurrentManagers%5B0%5D.ToBeDeleted=false&CurrentManagers%5B0%5D.ExtId=X00405982144&CurrentManagers%5B1%5D.ToBeDeleted=false [snip...] – solidau Jul 02 '13 at 22:02
  • Hmm. The only other obvious (possible) issue I can see is that when model-binding, if the indexing of the collection is broken (skips a number), everything after the last sequential number is ignored/discarded. I don't see that what you're doing should have that issue, though. – Tieson T. Jul 02 '13 at 23:05
  • if i change the type to FormCollection, it gets populated. But of course i dont want to bind to that... – solidau Jul 02 '13 at 23:12
  • they are in order, incremented by 1. – solidau Jul 02 '13 at 23:14
  • I ended up just switching it and going with Partials. Probably the more DRY way to go anyway.... – solidau Jul 03 '13 at 00:10
  • 1
    If you have time, you should post an example of what you did to solve the issue - I'm sure someone will find it useful. That, and you can accept your own answer. – Tieson T. Jul 03 '13 at 00:32

1 Answers1

1

Hmm. I think this is ultimately the problem; here's what you're posing:

CurrentManagers[0].ToB‌​eDeleted=true&CurrentManagers[0].ToBeDeleted=false&CurrentManagers[0].Ext‌​Id=X00405982144

Your model is an AddListManagersViewModel that has a collection of CurrentManagers. So, you're posting an array of DeleteableManagerViewModel, which isn't getting bound to the "wrapper" model. You can try changing the model parameter to

params DeleteableManagerViewModel[] model

I don't ever use the EditorFor extensions, though, so I'm just guessing...

Tieson T.
  • 20,774
  • 6
  • 77
  • 92
  • You are onto something with it not binding the wrapper model. When I change it to not include the wrapping, it works and binds properly. But the problem is (I think) i need the wrapper, because the page actually displays two forms (another one to add to the managers, which works and binds even with the wrapper...) – solidau Jul 02 '13 at 23:38