Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 Razor model binder and inherited collections

I hope I'm not missing something incredibly obvious here but is there any reason why model binder is always having trouble binding a view model that inherits from a collection?

Lets say I want to show a paged list and display a combo box and add button above it (dealing with simple lists). Involved classes would look like:

public class PagedList<T> : List<T>
{
    public int TotalCount { get; set; }
}

And then a view model that looks like:

public class MyViewModel : PagedList<ConcreteModel>
{
    public IEnumerable<ChildModel> List { get; set; }
    public int? SelectedChildModelId { get; set; }
}

So in the view (Razor):

@model MyViewModel 
@using (Html.BeginForm())
{
    @Html.DropDownListFor(model => model.SelectedChildModelId, new SelectList(Model.List, "ChildModelId", "DisplayName"))
}

And the controller HttpPost action:

public ActionResult(MyViewModel viewModel)
{
    ...
}

The above will cause viewModel in ActionResult to be null. Is there a logical explanation for it? From what I can tell it's specific only to view models that inherit from collections.

I know I can get around it with custom binder but the properties involved are primitive types and there isn't even any generics or inheritance.

I've reworked the view models to have the collection inherited type as properties and that fixes the issue. However I'm still scratching my head over why the binder breaks down on it. Any constructive thoughts appreciated.

like image 410
Ales Potocnik Hahonina Avatar asked Jun 21 '11 15:06

Ales Potocnik Hahonina


1 Answers

To answer my own question: All my models that have anything to do with collections no longer inherit from generic list or similar but instead have a property of the required collection type. This works much better because when rendering you can use

@Html.EditorFor(m => m.CollectionProperty)

And create a custom editor under Views/Shared/EditorTemplates for contained type. It also works beautifully with model binder since all individual items from collection get a index and the binder is able to auto bind it when submitted.

Lesson learned: if you plan to use models in views, don't inherit from collection types.

like image 158
Ales Potocnik Hahonina Avatar answered Sep 29 '22 22:09

Ales Potocnik Hahonina