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

MVC manually serializing complex object or model binding

我 运行 在 MVC 中遇到的最大问题之一是当我将复杂的 属性 (视图模型)附加到我的模型以用于表单时。例如,我有一个名为 Customer.cs 的模型。该客户(为简单起见)随时有 1 个订单。所以我给他一个属性的Customer.Order。客户有许多其他属性将他定义为一个独特的客户。 Order 属性 本身有一组独特的属性。所以我继续前进,构建我的控制器,其他模型值,最后我开始计算我的视图详细信息。
我首先定义表单本身。

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

这个表单声明基本上告诉视图,当用户单击提交时,这个表单中的所有内容都应该被序列化并发送到控制器。 首先,我为我的主模型 Customer.cshtml 创建了一个视图。它采用 Customer.cs 模型。

我专门为这个名为 Order.cshtml 的复杂对象创建了一个视图。它采用了一个 Order.cs 模型(因此我可以稍后在其他父模型上重用它,例如 Invoice 因为我很聪明并且会超前考虑。)所以我写了所有这些 javascript 并查看依赖于视图的逻辑是独立的并且可以与其他模型一起重用。我的声明文本框如下所示:

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

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

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

定义视图的所有属性。这将与默认绑定一起工作,一切都很好。除了,我已经在 JavaScript 中编写的代码呢?我必须仔细检查并将“Order_”附加到表格上所有对 ID 的引用。此外,这现在在模型之间不容易移动,每次我创建一个使用 Order 对象的新模型时我都必须重新创建这个视图,因为它现在采用 Customer.cs 模型。我还必须重写 javascript,或者想出一些奇特的方法来传递前缀 (ViewData)。这似乎不正确。我做错了什么?

如果您为所有使用 Order 的视图模型创建一个接口会怎么样:

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

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

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

如果是客户,您可以创建派生自 IWithOrder 的客户视图模型:

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

    public Customer Customer { get; set; }
}

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

如果你不想在 js 引用中附加 Order_,你也可以在 TextBoxForhtmlAttributes 参数中设置 html 元素的 id。