【问题标题】:MVC ViewModel not posting backMVC ViewModel 不回发
【发布时间】:2013-11-22 23:03:49
【问题描述】:

我正在使用 Viewmodel,但是当我提交表单时,我没有取回值。

我有一个这样的模型...

Public Class ProductSummaryModel

    Property productGUID As Integer
    Property productName As String
    Property productPrice As Double
    Property productSku As String
    Property categories As String()
    Property ShipsWithin As Nullable(Of Integer)
    <AllowHtml>
    Property productWebDescription As String
    Property ImageMainPath As String

End Class

然后我有一个像这样的 ViewModel...

Public Class ProductViewModel
    Public ProductSummary As ProductSummaryModel
End Class

这是我的控制器...

Public Function Add() As ActionResult ' Default View To Add  Item
    Dim prdsummary As ProductViewModel = New ProductViewModel
    Return View("Add", prdsummary)
End Function

在我的“添加”视图中,我关注...

<tr>
    <td>Price: </td>
    <td><%=Html.TextBoxFor(Function(f) f.ProductSummary.productPrice)%></td>
</tr>

问题是,当我提交表单时,我无法获取 POSTED 表单值。

    Public Function AddItem(ByVal Model As ProductViewModel) As ActionResult ' Add Item into DB

        Dim ajaxMessage As New AjaxFormResponse

        Dim prd As ProductSummaryModel = New ProductSummaryModel
        Model.ProductSummary = prd

        Dim skuID As Integer = 0
        msgbox(Model.ProductSummary.categories) ' Empty

End Function

可能有更好的方法来处理这个问题。

* 更新 **

我已经弄清楚问题出在哪里...当将模型传递给 ViewModel 时,我必须这样做...

Dim Product As ProductViewModel = New ProductViewModel
Dim ProductSummary As New ProductSummaryModel
Product.ProductSummary = ProductSummary
Return View("Add", Product)

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    为什么不使用 ProductSummaryModel 而不是 ProductViewModel 进行绑定。这样你就可以保持简单。如果可以,请避免嵌套绑定。 还要确保您在如下视图中使用,以及 HttpPost attr。在控制器中

    产品控制器

    Public Class ProductController
    Inherits Controller
    
    ' Main Action
    Public Function Main() As ActionResult 
        Dim prdViewModel As ProductViewModel = New ProductViewModel       
        prdViewModel.ProductSummary = New ProductSummaryModel
        Return View("Main", prdViewModel)
    End Function
    
    ' Partial Action
    Public Function Add() As ActionResult 
        Dim prdViewModel As ProductViewModel = New ProductViewModel
        prdViewModel.ProductSummary = New ProductSummaryModel
    
        Return View("Add", prdViewModel)
    End Function
    
    'POST Action from Partial View
    <HttpPost()> _
     Public Function AddItem(ByVal Model As ProductSummaryModel) As ActionResult ' Add Item into DB
       msgbox(Model.productPrice) ' Empty
    End Function
    
    End Class
    

    主视图

    <%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" 
        Inherits="System.Web.Mvc.ViewPage(Of MvcApplication2.ProductViewModel)" %>
    
    <asp:Content ID="manageTitle" ContentPlaceHolderID="TitleContent" runat="server">
        Main Page
    </asp:Content>
    
    <asp:Content ID="manageContent" ContentPlaceHolderID="MainContent" runat="server">
        <%
            Html.RenderPartial("_Add", Model.ProductSummary)
         %>
    </asp:Content>
    

    局部视图

        <%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of MvcApplication2.ProductSummaryModel)" %>
    
    <asp:Content ID="registerTitle" ContentPlaceHolderID="TitleContent" runat="server">
        Register
    </asp:Content>
    
    <asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server">
    
        <% Using Html.BeginForm("AddItem", "Product")%>
            <%: Html.AntiForgeryToken() %>
            <tr>
                <td>Price: </td>
                <td><%: Html.TextBoxFor(Function(f) f.productPrice) %></td>
            </tr>
            <input type="submit" value="Register" />
        <% End Using%>
    </asp:Content>
    

    更新视图模型

     Public Class ProductSummaryModel
    
        Property productGUID As Integer
        Property productName As String
        Property productPrice As Double
        Property productSku As String
        Property categories As String()
        Property ShipsWithin As Nullable(Of Integer)
        <AllowHtml>
        Property productWebDescription As String
        Property ImageMainPath As String
    
    End Class
    
    Public Class ProductViewModel
        Public ProductSummary As ProductSummaryModel
    End Class
    

    【讨论】:

    • Spock,这就是我之前的做法,问题是...我有多个 TABS,每个 TAB 本身就是一个局部视图。每个 Tab 都将包含自己的 ViewModel,然后我会将我的主模型(ProductViewModel)发送给 DB,而不是传递多个/单独的 ViewModel。
    • 在具有局部视图的主视图中,使用 Inherits="System.Web.Mvc.ViewPage(Of MvcApplication2.ProductViewModel)"。您的部分视图使用我发布的上述解决方案。当您从主视图调用它作为局部视图时,例如 Html.RenderPartial("_YourProduceSummaryPartialView, Model.ProductSummaryModel")。当然在你的部分视图@Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage(Of MvcApplication2.ProductSummaryModel)" %>
    • 这里有更多关于设置局部视图的信息forums.asp.net/p/1908088/…
    • 是的,我这样做了,但是现在当我尝试发布表单并尝试取回值时,我收到了对象实例错误消息。这就是我的控制器的样子: Public Function AddItem(ByVal Model As ProductViewModel) As ActionResult ' Add Item into DB MsgBox(Model.ProductSummary.productName)
    • 哪一行你得到对象实例错误?
    【解决方案2】:

    我发现两个问题:

    首先,当你这样做时,你会覆盖发布的值:

    Dim prd As ProductSummaryModel = New ProductSummaryModel
    Model.ProductSummary = prd
    

    来自您视图的模型中的ProductSummary 属性丢失,您只能在读取其属性时获得默认值。

    此外,您没有在视图中显示如何设置 categories 值。您是否允许此属性的用户输入或其他操作?

    【讨论】:

    • 我创建了一个新的 productssummary 实例,因为我得到了 Null 实例期望。是的,类别来自表单字段...为了保持问题简单,我没有发布该部分。 ProductSummary 是我的视图模型中的一个对象,但是当我尝试访问我的视图模型时出现异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多