Можете ли вы использовать ASP.NET MVC UpdateModel () со сложным объектом Model, содержащим список <T>? - PullRequest
2 голосов
/ 15 мая 2009

Я видел статьи и сообщения в блогах, указывающие на то, что я пытаюсь сделать, должно быть поддержано; однако я не смог заставить его работать, так что, надеюсь, кто-то может подтвердить, что он работает / не работает, и / или сказать мне, что я делаю неправильно.

У меня есть «сложная» модель (Invoice, содержащая список InvoiceItem), к которой я пытаюсь привязаться, и я хотел бы только обновить определенные атрибуты и определенные элементы / индексы в объектах List) Я считаю, что моя проблема в первую очередь в том, работает ли включение / исключение для данных Списка. Я пытаюсь использовать 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

Заранее спасибо!

1 Ответ

0 голосов
/ 23 сентября 2011

В вашей модели представления формы не объявляйте свойства для полей, которые вы не хотите связывать / обновлять MVC.

Связыватель MVC связывает только свойства с геттером / сеттером. Просто объявите свойства «только для чтения» как простые поля.

Вы также можете попробовать добавить атрибут [BindNever] в эти поля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...