如何使用复杂的对象与我的视图模型?

问题描述:

我刚开始使用MVC和有我正在开发的第一个项目。我一直试图用我的viewmodel和一个域对象来解决我的问题。如何使用复杂的对象与我的视图模型?

我的视图模型由一个客户对象和地址的对象。问题是,即使在针对客户和地址显示的所有属性,我只能保存更改,如果我明确地定义在视图模型中的每个属性。换句话说,我需要在视图模型中复制客户和地址对象的属性。这解决了我所有的问题。

我的问题是,是否需要显式定义视图模型中的每个属性,或者是否有一种方法,我可以用Customer类型的Customer属性和Address类型的Address属性来定义视图模型(这将是更简单)?

基于我我发现网上的东西,我想答案是我必须定义在视图模型中的每个属性。如果这是正确的,有没有办法为我自动做这个映射?

ASP.NET MVC 4

+0

我不明白为什么它不应该工作。你使用Html帮手吗?例如:@ Html.TextBoxFor(m => m.Address.City) 如果您正在使用它并包含所有

标记..您只需将[HttpPost]属性放在您的“更新”操作方法上并使其接收你的视图模型类型的一个参数。您视图中的值将自动绑定到参数变量。如果这没有帮助,请给我们一些代码来处理。 :) – Matt 2012-07-17 03:35:40
+0

另一件事..没有在文本框中使用的任何属性等将会丢失..对于任何你想保留的值(例如ID)..你应该使用@ Html.HiddenFor(m = > m.Customer.ID)或其他.. – Matt 2012-07-17 03:37:54

AutoMapper是映射颇为流行。

关于您的ViewModel定义,您希望您的ViewModel直接对应您的View。 ViewModel中不应该有一个属性不在View上使用。如果你有无逻辑的Views(你应该!),那么你的ViewModel的属性通常会直接与你在View上的字段相关。

当然,也有当两个的ViewModels将使用完全相同的特性次且从做这样的事情是什么阻止你:

public class CustomerViewModel { 
    public string Name { get; set; } 
    public AddressViewModel Address { get; set; } 
} 

public class AddressViewModel { 
    public string AddressLine1 { get; set; } 
} 

的问题,一旦你开始这样做,它的哦这样更容易让自己在不使用的地方一次或两次的属性打滑,也许扔在一些视图模型继承和你结束了非常混乱的ViewModels。

一般来说,我发现建议是有平的ViewModels。例如,如果您有两个需要“客户”和“地址”信息的“视图”,那么只需点击该视图,为两个视图创建一个单独的视图模型,然后复制这两个视图中的属性。

定义只有必要的属性您的查看需要在ViewModel。您的ViewModel可能看起来类似于您的域模型。但是你的视图模型只需要视图所需的属性。并非所有的属性。

例如:您可能有一个客户域模型,其属性为CustomerID, FirstName,LastName,CreatedDate,CreatedBy,LastModifiedDate

public class CustomerDomainModel 
{ 
    public int CustomerID { set;get;} 
    public string FirstName { set;get;} 
    public string LastName { set;get;} 
    public DateTime CreatedDate { set;get;} 
    public DateTime LastModifiedDate { set;get;} 
    public int CreatedBy { set;get;} 
} 

但在你的视图(UI - 形式),你可能需要显示的字段仅供FirstNameLastName。所以,你的视图模型可能只有3个属性(名字&姓氏+另一个属性有CustomerID也)

public class CustomerViewModel 
{ 
    //My view is going to use only these 3 fields. 
    // Hence no other properties i am defining here 
    public int CustomerID { set;get;} 
    public string FirstName { set;get;} 
    public string LastName { set;get;} 
} 

这2个(Domain对象到视图模型)之间的映射,您可以考虑使用Automapper