ASP.NET MVC Model binding to a list.

(scroll down for an in depth explanation)

I’m writing this post since I had a lot of problems finding out how Model binding works in ASP.NET MVC.

This behavior has changed in the beta and the final. This causes that some blog posts on the internet are inaccurate.

But let’s set things straight.

Create a MVC Project, leave everything default and add Product in your Models folders with the following (very simple) code:

namespace BlogPost.Models
{
    public class Product
    {
        public string Name { get; set; }
    }
}

Then add a ProductsController (in the Controllers folder) with the following code:

using System.Collections.Generic;
using System.Web.Mvc;
using BlogPost.Models;

namespace BlogPost.Controllers
{
    public class ProductsController : Controller
    {
        public ActionResult Add()
        {
            return this.View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Add(IList<Product> products)
        {
            return this.View();
        }
    }
}

And add the following view for the Add function:

image

With the following markup:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Add up to 10 products to the database
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        Add up to 10 products to the database</h2>
    <%
        using (Html.BeginForm())
        {
            for(int x = 0;x <= 9;x++)
            {
                %>
                <fieldset>
                    <legend>Product <%=x %>:</legend>
                    <input type="text" name="products[<%=x %>].Name" />
                </fieldset>
                <%
            }

            %><input type="submit" name="submitForm" value="Save products" /><%
        }
    %>
</asp:Content>

Now put a breakpoint in the Add function in your ProductsController that handles the Http Post.

image

Hit f5 and go to <your url>/Products/Add:

image

Enter 10 names, and hit the submit button at the bottom.

Visual Studio will break on your this.View(). Hover over your products parameter and you’ll see something in the lines of this:

image

Not too hard is it?

A little bit more in depth:

ASP.NET MVC binds your HTML input to your parameter through the default model binder. I recommend you read the source code available on http://aspnet.codeplex.com/SourceControl/changeset/view/23011

image

If you want to step through the source code using your application I refer you to Steve Sanderson’s excellent blog post.

If you take a look at the generated HTML source code you’ll notice this:

<fieldset>
    <legend>Product number 0:</legend>
    <input type="text" name="products[0].Name" />
</fieldset>
<fieldset>
    <legend>Product number 1:</legend>
    <input type="text" name="products[1].Name" />
</fieldset>

The name ‘products’ is VERY important, since this specifies that it your input should be bound to the ‘products’ parameter in your controller action.

Then the index between brackets: IT MUST START FROM 0 AND BE CONTINUES!

Then the .Name, which specifies that your input should be placed in the Name property (not just a public variable, but a property with a get/set) (see code above).

You can repeat this for multiple properties, and group them by product.

That’s it for simple model binding.

Hope it helps.

3 thoughts on “ASP.NET MVC Model binding to a list.”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>