我在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)的奇特方式。这似乎不正确。我做错了什么?
答案 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。