MVC手动序列化复杂对象或模型绑定

时间:2015-06-30 15:22:25

标签: javascript c# asp.net-mvc asp.net-mvc-3

我在MVC中遇到的最大问题之一是当我将复杂属性(视图模型)附加到我的模型以在表单上使用时。例如,我有一个名为Customer.cs的模型。该客户(为简单起见)随时有1个订单。所以我给他一个Customer.Order的财产。客户有许多其他属性将他定义为独特的客户。 Order属性本身具有一组唯一属性。所以我正在努力,构建我的Controller,其他模型值,最后我开始计算我的View细节 我首先定义表单本身。

@using (Html.BeginForm("Customer", "Home", FormMethod.Post, new { @id = "customerForm" })

此表单声明基本上告诉View,当用户单击Submit时,此表单中的所有内容都应序列化并发送到Controller。 首先,我为我的主要模型Customer.cshtml创建一个视图。它接受Customer.cs模型。

我专门为我创建的名为Order.cshtml的复杂对象创建了一个View。它接受一个Order.cs模型(所以我可以稍后在其他父模型上重用它,比如Invoice因为我很聪明并且提前考虑。)所以我写了所有这些javascript和视图逻辑,这取决于视图独立并可与其他模型重复使用。我的textboxfor声明看起来像这样:

@Html.TextBoxFor(m => m. OrderDate) 

当我点击提交时,我注意到的第一件事是订单对象中没有任何值被回发。所以我坐在那里进行调试,需要一段时间,但我终于弄清楚这不会这样。除非有单独序列化视图模型的方法,然后将其附加到父模型,即使这样你也必须编写一堆Javascript来手动覆盖默认表单提交过程,以及您可能正在制作的任何其他模型提交用于客户端字段验证。
我认为应该有一种更简单的方法来处理这个问题。我知道解决这个问题的方法,但它并不漂亮。您可以为Order.cs创建视图,以取代Customer.cs模型。然后,使用textboxfor声明,如:

@Html.TextBoxFor(m => m.Order.OrderDate) 

定义View上的所有属性。这将使用默认绑定,一切都很好。除了我用JavaScript编写的代码怎么样?我必须通过并将“Order_”附加到表单上列出的所有ID的引用。此外,现在不能在模型之间轻松移动,每次创建使用Order对象的新模型时,我都必须重新创建此View,因为它现在接受Customer.cs模型。我还必须重写javascript,或者想出一些传递前缀(ViewData)的奇特方式。这似乎不正确。我做错了什么?

1 个答案:

答案 0 :(得分:1)

如果为使用Order的所有视图模型创建界面,该怎么办?

interface IWithOrder
{
    Order Order { get; set; }
}

在常用的订单视图中使用此界面:

@model Project.ViewModels.IWithOrder
...
@Html.TextBoxFor(m => m.Order.OrderDate, new { Id = "OrderDate" }) 

如果是Customer,您可以创建Customer视图模型,该模型派生自IWithOrder:

public class CustomerViewModel : IWithOrder
{
    public Order Order { get; set; }

    public Customer Customer { get; set; }
}

现在您可以重用Order视图,但您的视图模型需要从IWithOrder派生。

如果您不想在js引用中附加htmlAttributes,也可以在Order_ TextBoxFor参数中设置html元素的ID。