title: Can you use ASP.NET MVC UpdateModel() with complex Model Object containing List<T>?
body: <p>I've seen articles and blog posts indicating what I am attempting to do should be supported; however, I have been unable to get it working so hopefully someone can confirm that it does/does not work and/or tell me what I am doing wrong.</p>
  
  <p>I have a "complex" model (Invoice containing a List of InvoiceItem) that I am attempting to bind to and I would only like to update certain attributes and certain items/indexes on the List objects).  I believe my issue is primarily with whether or not the include/exclude works for List data.  I am attempting to use UpdateModel() with its includeProperties, like so:</p>
  
  <pre><code>Public Function Edit(ByVal id As String, ByVal values As FormCollection)
      Dim invoice As Invoice = _getInvoice(id)
      UpdateModel(invoice, "", New String() {"InvoiceDate", "CustomerName", "Items[0].Price"})        
      'Do some stuff...
  End Function
  </code></pre>
  
  <p>All of my code is below...</p>
  
  <p>I have the following model:</p>
  
  <pre><code>Public Class Invoice
      Private _invoiceNumber As String
      Private _invoiceDate As DateTime
      Private _customerName As String
      Private _items As List(Of InvoiceItem)
      Public Property InvoiceNumber() As String
          Get
              Return _invoiceNumber
          End Get
          Set(ByVal value As String)
              _invoiceNumber = value
          End Set
      End Property
      Public Property InvoiceDate() As DateTime
          Get
              Return _invoiceDate
          End Get
          Set(ByVal value As DateTime)
              _invoiceDate = value
          End Set
      End Property
      Public Property CustomerName() As String
          Get
              Return _customerName
          End Get
          Set(ByVal value As String)
              _customerName = value
          End Set
      End Property
      Public Property Items() As List(Of InvoiceItem)
          Get
              Return _items
          End Get
          Set(ByVal value As List(Of InvoiceItem))
              _items = value
          End Set
      End Property
  End Class
  
  Public Class InvoiceItem
      Private _itemNumber As Integer
      Private _description As String
      Private _price As Decimal
      Public Property ItemNumber() As Integer
          Get
              Return _itemNumber
          End Get
          Set(ByVal value As Integer)
              _itemNumber = value
          End Set
      End Property
      Public Property Description() As String
          Get
              Return _description
          End Get
          Set(ByVal value As String)
              _description = value
          End Set
      End Property
      Public Property Price() As Decimal
          Get
              Return _price
          End Get
          Set(ByVal value As Decimal)
              _price = value
          End Set
      End Property
  End Class
  </code></pre>
  
  <p>I have the following View:</p>
  
  <pre><code>&lt;%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" 
      Inherits="System.Web.Mvc.ViewPage(Of MvcApplication2.Invoice)" %&gt;
  
  &lt;asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"&gt;
      &lt;title&gt;Edit&lt;/title&gt;
  &lt;/asp:Content&gt;
  
  &lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;
  
      &lt;h2&gt;Edit&lt;/h2&gt;
  
      &lt;%=Html.ValidationSummary()%&gt;
  
      &lt;% Using Html.BeginForm() %&gt;
  
          &lt;fieldset&gt;
              &lt;legend&gt;Fields&lt;/legend&gt;
              &lt;p&gt;
                  &lt;label for="InvoiceNumber"&gt;InvoiceNumber:&lt;/label&gt;
                  &lt;%= Html.TextBox("InvoiceNumber") %&gt;
                  &lt;%= Html.ValidationMessage("InvoiceNumber", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;label for="InvoiceDate"&gt;InvoiceDate:&lt;/label&gt;
                  &lt;%= Html.TextBox("InvoiceDate") %&gt;
                  &lt;%= Html.ValidationMessage("InvoiceDate", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;label for="CustomerName"&gt;CustomerName:&lt;/label&gt;
                  &lt;%= Html.TextBox("CustomerName") %&gt;
                  &lt;%= Html.ValidationMessage("CustomerName", "*") %&gt;
              &lt;/p&gt;
              &lt;%For x As Integer = 0 To ViewData.Model.Items.Count - 1%&gt;       
              &lt;p&gt;    
                  &lt;label for="Item&lt;%=ViewData.Model.Items(x).ItemNumber %&gt;"&gt;Item &lt;%=ViewData.Model.Items(x).ItemNumber%&gt;:&lt;/label&gt;
                  &lt;%=Html.Hidden("Items.Index", x)%&gt;
                  &lt;%=Html.TextBox(String.Format("Items[{0}].Description", x), ViewData.Model.Items(x).Description)%&gt;
                  &lt;%=Html.ValidationMessage("Description", "*")%&gt;
                  &lt;%=Html.TextBox(String.Format("Items[{0}].Price", x), ViewData.Model.Items(x).Price)%&gt;
                  &lt;%=Html.ValidationMessage("Price", "*")%&gt;
              &lt;/p&gt;
              &lt;%Next x%&gt;
              &lt;p&gt;
                  &lt;input type="submit" value="Save" /&gt;
              &lt;/p&gt;
          &lt;/fieldset&gt;
  
      &lt;% End Using %&gt;
  
  
  &lt;/asp:Content&gt;
  </code></pre>
  
  <p>And here is my Controller:</p>
  
  <pre><code>Public Class InvoicingController
      Inherits System.Web.Mvc.Controller
  
      Private Function _getInvoice(ByVal id As String) As Invoice
          Dim invoice As New Invoice
          invoice.InvoiceNumber = id
          invoice.CustomerName = "John Doe"
          invoice.InvoiceDate = DateTime.Now
          invoice.Items = New List(Of InvoiceItem)
          For x As Integer = 1 To 5
              Dim item As InvoiceItem = New InvoiceItem
              item.ItemNumber = x
              item.Description = String.Format("Item {0}", x)
              item.Price = 100 + x
              invoice.Items.Add(item)
          Next
          Return invoice
      End Function
  
      &lt;AcceptVerbs(HttpVerbs.Post)&gt; _
      Function Edit(ByVal id As String) As ActionResult
          Dim invoice As Invoice = _getInvoice(id)
          Return View(invoice)
      End Function
  
  
  
          'UpdateModel(invoice, "", New String() {"InvoiceDate", "CustomerName", "Items"}) 'NOTE: THis line appears to update any InvoiceItem attributes that are supplied
          UpdateModel(invoice, "", New String() {"InvoiceDate", "CustomerName", "Items[0].Price"}) 'This line does not allow the first item's Price to be updated.
  
          Return View()
  
      End Function
  
  End Class
  </code></pre>
  
  <p>Thanks in advance!</p>