I've seen a number of examples where the create and edit action methods are bound to a single object as such:
public ActionResult Create (Person person) {}
with view code like Html.Textbox(person.Name, ViewData.Model.Name)
***
I was wondering if it is possible to bind to multiple objects ... something like:
public ActionResult Create (Person person, ContactInfo, contactInfo) {}
with view code like Html.Textbox(person.Name, ViewData.Model.Name) and Html.Textbox(contactInfo.Address1, ViewData.Model.Contact.Address1)
***
Or even better, is it possible to bind a collection of another object ... something like:
public ActionResult Create (Person person, ContactInfo[], contactInfo) {}
with view code like Html.Textbox(person.Name, ViewData.Model.Name) and Html.Textbox(contactInfo.Address1, ViewData.Model.Contacts[0].Address1) and Html.Textbox(contactInfo.Address1, ViewData.Model.Contacts[1].Address1)
So is this even possible? If so, any suggested practices and/or examples out there I could take a look at? Any ideas would be much appreciated!
No, this really doesn't answer my question. I'm aware of how to use a strongly typed collection of objects to a view ... what I'm asking is, "Is it possible to put that collection of objects together in a single form and pass them back to a create/edit
action method that automatically binds the values to the correct objects for persisting?"
So, lets say I have a form that has data for a Person object and a collection of ContactInfo objects. I'd like to do something like prefix all the person object data with "person" and post it, along with all the contactInfo object data (prefixed by "contactInfo"
and all loaded into a dictionary named "Contacts") to an action method such as public ActionResult Create (Person person, ContactInfo[] contacts) {}
This is pretty easy to do in Rails but I'm not sure if it is possible ... or if so ... what is the best way to do it in ASP.NET MVC.
It is possible in ASP.NET MVC in manner that you are using in your first post. So you can specify more parameters of your action method. The rules for binding are the same as if you are using action method with one parameter. So you can specify custom
ModelBinder for your types and you can specify some attributes of binding by applying
BindAttribute to action method parameters. This all is described in this article:
http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
Don't forget to click "Mark as Answer" on the post that helped you.
I look over MVC beta source code from codeplex and found something alluring in DefaulModelBinder type that intercept calls to any Controller action method. That is (in BindModel method):
if (bindingContext.ModelType.IsArray) {
return new ModelBinderResult(CreateArray(bindingContext, bindingContext.ModelType.GetElementType()));
}
I draw a conclusion that it is possible to bind some collections. After some investigations I get some test solution. This some extracts from it:
public class BindingObject
{
public OtherDataObject OtherData { get; set; }
public DataObject[] DataArray { get; set; }
}
public class DataObject
{
public int Id { get; set; }
public string Data { get; set; }
}
public class OtherDataObject
{
public int Id { get; set; }
public string OtherData { get; set; }
}
<form action="Data/Save" method="post">
<% int index = 0; %>
<% foreach (var item in (ViewData.Model as MvcApplication.Models.BindingObject).DataArray as IEnumerable<MvcApplication.Models.DataObject>) { %>
<div>
<%= Html.Hidden("BindingObject.DataArray.index", index)%>
<%= Html.Hidden("BindingObject.DataArray[" + index + "].Id", item.Id) %>
<%-- Syntax may be HTML-clear --%>
<input name="BindingObject.DataArray[<%= index %>].Data" type="text" value='<%= item.Data %>' />
</div>
<% index++; } %>
<input name="BindingObject.OtherData.Id" type="text" />
<input name="BindingObject.OtherData.OtherData" type="text" />
<input type="submit" value="Save" />
</form>
wgpubs
Member
15 Points
12 Posts
Bind to multiple objects?
Nov 22, 2008 03:10 AM|LINK
Hi Folks,
I've seen a number of examples where the create and edit action methods are bound to a single object as such:
public ActionResult Create (Person person) {}
with view code like Html.Textbox(person.Name, ViewData.Model.Name)
***
I was wondering if it is possible to bind to multiple objects ... something like:
public ActionResult Create (Person person, ContactInfo, contactInfo) {}
with view code like Html.Textbox(person.Name, ViewData.Model.Name) and Html.Textbox(contactInfo.Address1, ViewData.Model.Contact.Address1)
***
Or even better, is it possible to bind a collection of another object ... something like:
public ActionResult Create (Person person, ContactInfo[], contactInfo) {}
with view code like Html.Textbox(person.Name, ViewData.Model.Name) and Html.Textbox(contactInfo.Address1, ViewData.Model.Contacts[0].Address1) and Html.Textbox(contactInfo.Address1, ViewData.Model.Contacts[1].Address1)
So is this even possible? If so, any suggested practices and/or examples out there I could take a look at? Any ideas would be much appreciated!
Thanks - wayde
Erwin21
Contributor
2166 Points
354 Posts
Re: Bind to multiple objects?
Nov 22, 2008 12:04 PM|LINK
Take a look at this thread: http://forums.asp.net/p/1242984/2278326.aspx
wgpubs
Member
15 Points
12 Posts
Re: Bind to multiple objects?
Nov 22, 2008 04:05 PM|LINK
No, this really doesn't answer my question. I'm aware of how to use a strongly typed collection of objects to a view ... what I'm asking is, "Is it possible to put that collection of objects together in a single form and pass them back to a create/edit action method that automatically binds the values to the correct objects for persisting?"
So, lets say I have a form that has data for a Person object and a collection of ContactInfo objects. I'd like to do something like prefix all the person object data with "person" and post it, along with all the contactInfo object data (prefixed by "contactInfo" and all loaded into a dictionary named "Contacts") to an action method such as public ActionResult Create (Person person, ContactInfo[] contacts) {}
This is pretty easy to do in Rails but I'm not sure if it is possible ... or if so ... what is the best way to do it in ASP.NET MVC.
Thanks - wg
Augi
Contributor
6730 Points
1142 Posts
Re: Bind to multiple objects?
Nov 22, 2008 05:10 PM|LINK
It is possible in ASP.NET MVC in manner that you are using in your first post. So you can specify more parameters of your action method. The rules for binding are the same as if you are using action method with one parameter. So you can specify custom ModelBinder for your types and you can specify some attributes of binding by applying BindAttribute to action method parameters. This all is described in this article: http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
KDStranger
Member
2 Points
1 Post
Re: Bind to multiple objects?
Nov 22, 2008 09:37 PM|LINK
Hi.
I'm interested this subject too.
I look over MVC beta source code from codeplex and found something alluring in DefaulModelBinder type that intercept calls to any Controller action method. That is (in BindModel method):
if (bindingContext.ModelType.IsArray) {
return new ModelBinderResult(CreateArray(bindingContext, bindingContext.ModelType.GetElementType()));
}
I draw a conclusion that it is possible to bind some collections. After some investigations I get some test solution. This some extracts from it:
public class BindingObject { public OtherDataObject OtherData { get; set; } public DataObject[] DataArray { get; set; } } public class DataObject { public int Id { get; set; } public string Data { get; set; } } public class OtherDataObject { public int Id { get; set; } public string OtherData { get; set; } }<form action="Data/Save" method="post">
<% int index = 0; %>
<% foreach (var item in (ViewData.Model as MvcApplication.Models.BindingObject).DataArray as IEnumerable<MvcApplication.Models.DataObject>) { %>
<div>
<%= Html.Hidden("BindingObject.DataArray.index", index)%>
<%= Html.Hidden("BindingObject.DataArray[" + index + "].Id", item.Id) %>
<%-- Syntax may be HTML-clear --%>
<input name="BindingObject.DataArray[<%= index %>].Data" type="text" value='<%= item.Data %>' />
</div>
<% index++; } %>
<input name="BindingObject.OtherData.Id" type="text" />
<input name="BindingObject.OtherData.OtherData" type="text" />
<input type="submit" value="Save" />
</form>
[AcceptVerbs(HttpVerbs.Post)]public ActionResult Save(BindingObject BindingObject, FormCollection form)
{ }
Binding is automated and as result we get a fully filled object.
I got some issues. I haven't bind array directly like that: public ActionResult Save(DataObject[] DataObject, FormCollection form)
...but may be I make something wrong.
Hope, it will helpful.