Reputation: 724
I realize something like this has been asked, but this may be a little different.
Below is my Event object:
Event : IEvent
public int Id
public string Title
public List<EventContact> Contacts
And EventContact:
EventContact
public int Id
public string Name
public string Email
So, an Event
has a list of EventContact
objects. Now, Event also implements IEvent - hence the custom model binder. I use IEvent
instead of Event, so when the default model binder tries to do its thing, it lets me know it can't create an `IEvent'.
I have my view with populated with the contact info:
<input type="text" name="contact[0].Name" value="DB Value"/>
<input type="text" name="contact[1].Name" value="DB Value"/>
<input type="text" name="contact[2].Name" value="DB Value"/>
<input type="text" name="contact[0].Email" value="DB Value"/>
<input type="text" name="contact[1].Email" value="DB Value"/>
<input type="text" name="contact[2].Email" value="DB Value"/>
<!-- Event fields, etc -->
So, in my custom model binder I am able to see all the values - sweet! The only thing is, I'm really not sure how to get all the contact fields and create a list of contacts from them, along with binding all the Event fields.
Upvotes: 2
Views: 823
Reputation: 724
To accomplish the above, I simply queried the existing binding context's ValueProvider
for all EventContact fields and sent that along to the default model binder with a new binding context:
IDictionary<string, ValueProviderResult> contactValueProvider = bindingContext.ValueProvider
.Select(t => new { t.Key, t.Value })
.Where(t => t.Key.Contains("EventContact"))
.ToDictionary(t => t.Key, t => t.Value);
ModelBindingContext contactBindingContext = new ModelBindingContext()
{
ModelName = "EventContact",
ModelState = bindingContext.ModelState,
ModelType = typeof(List<EventContact>),
PropertyFilter = bindingContext.PropertyFilter,
ValueProvider = contactValueProvider
};
_event.Contacts = ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, contactBindingContext) as IQueryable<EventContact>;
It works, so I'm happy :P
Upvotes: 1