views:

2447

answers:

3

I have a form which needs to populate 2 models. Normally I use a ModelBinderAttribute on the forms post action i.e.

    [Authorize]
    [AcceptVerbs("POST")]
    public ActionResult Add([GigBinderAttribute]Gig gig, FormCollection formCollection)
    {
       ///Do stuff
    }

In my form, the fields are named the same as the models properties...

However in this case I have 2 different models that need populating.

How do I do this? Any ideas? Is it possible?

A: 

The UpdateModel or TryUpdateModel method can be used to do this. You can pass through the model, the model you wish to bind, the prefix of the items you wish to bind to that model and the form. For example if your Item model has form variables of "Item.Value" then your update model method would be:

UpdateMode(modelObject, stringPrefix, formCollection);

If you're using the entity framework, it's worth pointing out that the UpdateModel method doesn't always work under some conditions. It does work particularly well with POCOs though.

Odd
Is it possible to do this automatically by using attributes?
ListenToRick
+4  A: 

In cases like this, I tend to make a single model type to wrap up the various models involved:

class AddModel
{
     public Gig GigModel {get; set;}
     public OtherType OtherModel {get; set;}
}

...and bind that.

Craig Stuntz
You just have to make sure that your form field names are prefix with the name of the property, for example Gig.Name, Gig.Date and OtherModel.SomeProperty
Jake Scott
As of MVC 2, if you use EditorFor(model => model.Gig), it does the prefix work for you. You can still consume all the sub-models as separate parameters, though, allowing easier breakdown of attributes (e.g., `ActionResult SomePostAction([Bind(Include = {"list", "of", "bindable", "fields"}, Prefix = "Gig"]GigModel gig, [Bind(...)]OtherModel other)`). Then you just need to build up a composite model from there: `var m = new AddModel { Gig = gig, OtherType = other }`.
patridge
+5  A: 

Actually... the best way is to do this:

public ActionResult Add([GigBinderAttribute]Gig gig, [FileModelBinderAttribute]File file) {

}

You CAN use multiple attributes!

ListenToRick