views:

86

answers:

1

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.

Any and all help is appreciated!

+1  A: 

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

Dan
Also, I downloaded the MVC source and debugged with that - highly recommend doing that if you are at a dead-end. Interesting stuff :)
Dan