【问题标题】:Can you use ASP.NET MVC UpdateModel() with complex Model Object containing List<T>?您可以将 ASP.NET MVC UpdateModel() 与包含 List<T> 的复杂模型对象一起使用吗?
【发布时间】:2009-05-15 17:13:26
【问题描述】:

我看到文章和博客文章表明我正在尝试做的事情应该得到支持;但是,我一直无法让它工作,所以希望有人可以确认它确实/不起作用和/或告诉我我做错了什么。

我有一个“复杂”模型(包含 InvoiceItem 列表的发票),我试​​图绑定到该模型,我只想更新列表对象上的某些属性和某些项目/索引)。我相信我的问题主要在于包含/排除是否适用于列表数据。我正在尝试将 UpdateModel() 与它的 includeProperties 一起使用,如下所示:

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

我所有的代码都在下面...

我有以下型号:

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

我有以下观点:

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="System.Web.Mvc.ViewPage(Of MvcApplication2.Invoice)" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <title>Edit</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Edit</h2>

    <%=Html.ValidationSummary()%>

    <% Using Html.BeginForm() %>

        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="InvoiceNumber">InvoiceNumber:</label>
                <%= Html.TextBox("InvoiceNumber") %>
                <%= Html.ValidationMessage("InvoiceNumber", "*") %>
            </p>
            <p>
                <label for="InvoiceDate">InvoiceDate:</label>
                <%= Html.TextBox("InvoiceDate") %>
                <%= Html.ValidationMessage("InvoiceDate", "*") %>
            </p>
            <p>
                <label for="CustomerName">CustomerName:</label>
                <%= Html.TextBox("CustomerName") %>
                <%= Html.ValidationMessage("CustomerName", "*") %>
            </p>
            <%For x As Integer = 0 To ViewData.Model.Items.Count - 1%>       
            <p>    
                <label for="Item<%=ViewData.Model.Items(x).ItemNumber %>">Item <%=ViewData.Model.Items(x).ItemNumber%>:</label>
                <%=Html.Hidden("Items.Index", x)%>
                <%=Html.TextBox(String.Format("Items[{0}].Description", x), ViewData.Model.Items(x).Description)%>
                <%=Html.ValidationMessage("Description", "*")%>
                <%=Html.TextBox(String.Format("Items[{0}].Price", x), ViewData.Model.Items(x).Price)%>
                <%=Html.ValidationMessage("Price", "*")%>
            </p>
            <%Next x%>
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% End Using %>


</asp:Content>

这是我的控制器:

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

    <AcceptVerbs(HttpVerbs.Post)> _
    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

提前致谢!

【问题讨论】:

    标签: asp.net-mvc model


    【解决方案1】:

    在您的表单视图模型中,不要为您不希望 MVC 绑定/更新的字段声明属性。

    MVC 绑定器仅将属性与 getter/setter 绑定。 只需将“只读”属性声明为简单字段即可。

    您也可以尝试在这些字段上添加 [BindNever] 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 2010-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多