M05Pr1mty
M05Pr1mty

Reputation: 731

MVC3 Binding a custom Collection

As per : MVC3 Model binding pagedlist to ViewModel with custom EditorTemplate and Partial View

See above question for code snippets

The problem i am having now surrounds binding the custom IPagedList collection. The model binder attempts to bind the values to the property on the ViewModel but is unable to create an instance of the interface (no suprises there).

So how can i bind values back to my viewModel by instantiating a concrete PagedList class when the values are bound? As i understand it the IEnumerable binder does this for a List or similar derivitive, so how can i do this for my custom class/interface?

Do i need a custom model binder for this? If so any information or code tips on this is great!

Any help greatly appreciated thanks.

Update:

Changing the ViewModel to include an overriden default constructor which initialises the Interface like so:

public class RequestCreateViewModel : ViewModelBase
{
    public IPagedList<CreateRequestModel> PagedList { get; set; }

    public RequestCreateVieWModel()
    {
        PagedList = new PagedList<RequestCreateModel>(new List<RequestCreateModel>(), new PagingOptions());
    }

.. appears to allow the default model binder to work as per my comment. But it doesnt seem like a great solution, mainly because im needing to infer new object parameters for the PagedList object each time a ViewModel is created. Am i needlessly worrying?

Upvotes: 2

Views: 659

Answers (1)

Ken Brittain
Ken Brittain

Reputation: 2265

Look at the source for DefaultModelBinder.cs in the ASP.NET MVC project on Codeplex. The comment in the BindComplexModel sums it all up:

// special-case IDictionary<,> and ICollection<>

If the MVC framework special cases those types then you will need to create a custom model binder for your type. But the solution you provide works...why? Your type is does not implement the ICollection or IDictionary special cases. The default code path calls the default constructor for a model type:

// fallback to the type's default constructor
return Activator.CreateInstance(typeToCreate);

Your default constructor creates the type you need. Therefore, no error. No default constructor, no object instance and as you have pointed out, you get an error.

You asked for more ideas. How about leaving what you have. It works. Writing a custom model binder would just be more work at this point. More code to accomplish the same thing.

Upvotes: 1

Related Questions