Does the Model Binder in ASP.NET MVC Beta Support List<T>?
Asked Answered
T

5

9

Take the example classes below. I want to display the customer and two addresses (from a LIST) on a form. Does the model binder in MVC beta support this or will I have to write my own custom binder?

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Address> Addresses { get; set; }

    public Customer()
    {
        Addresses = new List<Address>();
    }

}

public class Address
{
    public int Line1 { get; set; }
    public int Line2 { get; set; }
    public int City { get; set; }
    public int State { get; set; }
    public int Zip { get; set; }
}

How would you code the fields? Like this?

<!-- some HTML formatting -->
<%= Html.TextBox("customer.address.line1", ViewData.Customer.Address[0].Line1)%>
<!-- some more HTML formatting -->
<%= Html.TextBox("customer.address.line1", ViewData.Customer.Address[1].Line1)%>
<!-- end of HTML form formatting -->
Theosophy answered 2/1, 2009 at 17:29 Comment(0)
G
5

I've never tried it, but see this post, it's about model binding to a list, maybe it can help you.

Goran answered 2/1, 2009 at 17:36 Comment(0)
I
1

Use MvcContrib's NameValueDeserializer to make it simpler. Let's assume that your page derives from ViewPage<Customer>. You can do this:

<%= Html.TextBox("Address[0].Line1", ViewData.Model.Address[0].Line1)%>
<%= Html.TextBox("Address[1].Line1", ViewData.Model.Address[1].Line1)%>

And this:

public ActionResult Save([Deserialize]Customer customer)

And the customer will be deserialized from the form post with the address collection populated. Your indexes do not have to be in sequence -- this supports cases where you want to remove rows on the client side before the post occurs.

In the case that you are deserializing something from the view data dictionary (instead of the Model), then the syntax is like [Deserialize("customer")], where "customer" is the prefix.

You might find this blog post interesting and relevant.

Issue answered 3/1, 2009 at 15:32 Comment(0)
T
1

Just to make this complete. It's important that you use the hidden fields with the name Index. So my code above becomes this:

<!-- some HTML formatting -->
<%= Html.Hidden("customer.address.Index", 0) %>
<%= Html.TextBox("customer.address[0].line1", ViewData.Customer.Address[0].Line1)%>
<!-- some more HTML formatting -->
<%= Html.Hidden("customer.address.Index", 1) %>
<%= Html.TextBox("customer.address[1].line1", ViewData.Customer.Address[1].Line1)%>
<!-- end of HTML form formatting -->

It works like a charm!

Theosophy answered 5/1, 2009 at 18:37 Comment(1)
I think I'll need something like this in the near future, nice question.Scutcheon
R
0

You can pass an object list with ViewData like that, but you need to change some of the lines. Read more here:

http://weblogs.asp.net/scottgu/archive/2007/12/06/asp-net-mvc-framework-part-3-passing-viewdata-from-controllers-to-views.aspx

and here:

ASP.NET MVC: How do I pass a list (from a class in Model) to a repeater in a View?

Hope this helps


Edit


If you use a model, you need to set up the DataContext first and select the list, but sure you can use the classes generated if you use LINQ.

Rabbet answered 2/1, 2009 at 17:36 Comment(0)
A
0

I defined a similar object. I followed the post on binding to a list as referenced above, While the binding works,I was unable to use the Bind whitelist or blacklist in the controller's action parameter. THe model is an IList

Algorism answered 2/1, 2009 at 19:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.