ASP.NET MVC视图模型的最佳实践

时间:2011-06-16 19:35:23

标签: asp.net-mvc viewmodel

我的ASP.NET MVC站点连接到WCF服务以获取数据。 WCF服务返回如下数据协定:

[DataContract]
public class Person
{
    [DataMember]
    public string First { get; set; }

    [DataMember]
    public string Last { get; set; }
}

我的MVC项目中的视图模型如下所示:

public class MyViewModel
{
    public string SomeExtraField1 { get; set; }
    public string SomeExtraField2 { get; set; }
    public string SomeExtraField3 { get; set; }

    public Person Person { set; set; }
}

我的视图模型是否应引用从数据服务返回的“Person”数据协定?或者我应该在我的MVC项目中创建一个新的“Person”类来反映“Person”数据协定中的属性?

WCF服务调用隐藏在接口后面。似乎有接口引用数据契约使我的界面漏洞抽象。但是,我有一些人认为在我的MVC项目中创建一个额外的“Person”类来反映数据合同是代码膨胀。

围绕此类分层/解耦的最佳做法是什么?

2 个答案:

答案 0 :(得分:17)

  

我的视图模型是否应引用从数据服务返回的“Person”数据协定?

不,避免这种情况,它会让开发人员误以为他们正在使用视图模型。在进行代码审查时,我经常会看到这样的代码:

public class MyViewModel
{
    public SomeDomainModel1 Model1 { get; set; }
    public SomeDomainModel2 Model2 { get; set; }
    ...
}

那是错的。当我批评他们没有使用视图模型时,他们告诉我这个并告诉我:“Darin,看,我正在使用视图模型”,遗憾的是视图模型不应该如何工作。它们不是域模型的包装器。

  

或者我应该在MVC项目中创建一个新的“Person”类来反映“Person”数据合约的属性?

是的,您可以创建PersonViewModel并仅包含您的视图当然需要的属性。

或者,如果您正在设计此视图模型的特定视图仅需要一些属性,您也可以使它看起来像这样:

public class MyViewModel
{
    public string SomeExtraField1 { get; set; }
    public string SomeExtraField2 { get; set; }
    public string SomeExtraField3 { get; set; }

    // this would be for example the concatenation of your domain model 
    // first name and last name as that's what this particular view needs to 
    // display
    public string PersonFullName { set; set; }
}

就您的域模型和视图模型之间的转换而言,AutoMapper只是简单地说:优秀。

答案 1 :(得分:3)

我想创建一个Mapper层,它将在WCF Person类和“镜像”Person类之间进行转换。这样你就可以将你的MVC实现绑定到POCO而不是直接绑定到WCF。这增加了在不需要触摸MyViewModel的情况下将WCF换成另一个服务的能力(松散耦合)。