2013-09-10 64 views
5

ASP.NET | MVC 4 | C#| WCFASP.NET MVC - 模型的WCF类

我正在使用WCF Web服务作为从表示层(MVC)到数据层(实体)的中介。为了简化将数据模型数据从MVC移动到Web服务,我想我会在WCF中使用代理类,以便有一个集中的类。不幸的是,这导致模型中属性的MVC装饰丢失。有没有一种创建MVC视图模型的集中式类的好方法,还可以作为WCF服务的传输方法?

Automapping是一个选项,但我相信这需要两个相同的类。一个在MVC端,另一个在WCF端。如果在课堂上更改了属性,这仍然会要求我在双方进行更改。

任何其他建议,将不胜感激。谢谢!

编辑::例

这里是模型包含的记录

public class ReconcileModel 
{ 
    #region PROPERTIES 

    public List<ReconcileItem> ReconcileItems { get; set;} 

    #endregion 

    #region CONSTRUCTORS 

    public ReconcileModel() 
    { 
     ReconcileItems = new List<ReconcileItem>(); 
    } 

    #endregion 
} 

表下面是一个类来表示该表中每条记录的页面。

public class ReconcileItem 
{ 
    #region PROPERTIES 

    public int ID { get; set; } 
    public string Description { get; set; } 
    public string LastLocation { get; set; } 
    public string LastRead { get; set; } 
    public string IntendenLocation { get; set; } 
    public string PickId { get; set; } 
    public string OEM { get; set; } 
    public string LotNumber { get; set; } 
    public string SerialNumber { get; set; } 
    public DateTime ExpirationDate { get; set; } 
    public string ReconcileReason { get; set; } 
    public string RemoveReason { get; set; } 


    #endregion 

    #region CONSTRUCTORS 

    public ReconcileItem() 
    { 
    } 

    #endregion 
} 

类的WCF合同表示上面会

[DataContract] 
public class ReconcileItem 
{ 
    [DataMemeber] 
    public int ID { get; set; } 
    [DataMember] 
    public string Description { get; set; } 
    [DataMember] 
    public string LastLocation { get; set; } 
    [DataMember] 
    public string LastRead { get; set; } 
    [DataMember] 
    public string IntendenLocation { get; set; } 
    [DataMemeber] 
    public string PickId { get; set; } 
    [DataMember] 
    public string OEM { get; set; } 
    [DataMember] 
    public string LotNumber { get; set; } 
    [DataMember] 
    public string SerialNumber { get; set; } 
    [DataMember] 
    public DateTime ExpirationDate { get; set; } 
    [DataMember] 
    public string ReconcileReason { get; set; } 
    [DataMember] 
    public string RemoveReason { get; set; } 
} 

如果我想更新这个记录,类被发送到WCF服务,映射到相应的实体框架类,并保存到数据库。为了简化转移,我想我只是把这个类放在WCF项目中,并在MVC项目中引用它。然后我可以在WCF和MVC之间传回类。另外,如果我更新了WCF中的类,那么它将反映在MVC中。这就是集中式的意思。

+0

你的问题有点含糊。你可以向我们介绍一些代码,例如显示你的意思是“集中班”吗? – Steven

+0

@Steven看到编辑,让我知道如果澄清的东西。谢谢! – Will

回答

2

就像Adrian一样,我怀疑你是否真的需要在数据库和MVC服务之间使用WCF服务。对于与数据库进行对话的客户端应用程序(Win Forms,WPF),这是更可能的情况。我目前正在对在这里我们使用WCF作为中间层一个双赢的窗体项目,我们做以下几点:

  • 我们有一个客户端和WCF/BL之间共享的组件(所谓的“合同”) 。
  • 此“合同”程序集包含通过WCF和通过WCF发送的所有DTO。
  • 我们通过在服务引用设置中设置'指定引用程序集中的重用类型',将WCF客户端代理配置为使用约定程序集(而不是让WCF重新生成所有DTO)。
  • 我们用DataAnnotations属性(和其他元数据)来装饰这些DTO。
  • 我们不要装饰那些具有WCF属性的DTO。 WCF不需要它们序列化DTO。他们是可选。如果可以,请将它们留在外面。它只是混乱你的代码。
  • 由于客户端使用相同的程序集,我们可以在客户端上使用DataAnnotations。
  • 我们也在服务器上进行验证。
  • 我们使用AutoMapper来完成大部分从实体到DTO的样板映射(但从来没有其他方法)。坦率地说,你甚至不让WCF序列化我们的DTO,但是使用JSON.NET和WCF只是发送和接收(纯文本)JSON,因为JSON.NET在序列化和反序列化时更加灵活数据结构。例如,我们使用JSON.NET来(去)序列化不可变的对象结构。尝试使用WCF。这将会惨败。

最重要的是,我们做的:

  • 使用视图模型类的添加客户端功能。
  • 在合约程序集中添加自定义的DataAnnotation验证,以允许验证在客户端和服务器上运行。
  • 添加一个IValidator<T>抽象(某种)以允许服务器或客户端特定的验证(通过将实现放置在业务层或客户端应用程序中)。
  • 使用异常将传输服务器特定的验证错误返回给客户端。
+0

感谢您的信息,它非常丰富。基本上我正在考虑让ViewModel类成为DTO。将这些类自动映射到WCF类,然后使用Controller将该类传递给WCF方法以添加/更新/删除。按照您所描述的方式将它们放入“合同”组件中是否有优势?而不是仅仅在WCF中定义它们? – Will

+0

如果您没有将它们放入自己的程序集并在服务器和客户端之间共享该程序集,则意味着Visual Studio必须为您生成客户端代理,并将在客户端上重新生成DTO。这不仅会导致你有一大堆额外的(生成的)代码,VS将永远不会重新生成客户端上的任何属性(如DataAnnotations属性)。换句话说,您将丢失您在这些DTO上定义的所有元数据。 – Steven

2

你可以使用你的实体,但创建视图模型,并把你的数据注释,而不是。有很多关于如何在项目中进行验证的讨论。一般来说,它几乎总是一个给定的,它需要发生在用户界面,然后通常在其他地方。我会避免试图集中它,因为这永远不会工作(一个尺寸很少适合所有)。

关于楔入WCF层的问题之内您的解决方案,除非有很好的理由,否则我会不惜一切代价避免这样做。我已经看到这种事情多次出错了。它带来了很多负面影响。在我处理的两个商业案例中,最终会有太多的端点和太多的讨厌。它能够将业务逻辑放入实体并通过网络使用这些方法,使得维护成为一场噩梦,并且没有足够的硬件和精心设计(如果托管在单个服务器上),最终可能不得不使用命名管道获得您需要的速度,这会抵消您使用WCF获得的任何分布式优势。

您最好将重处理任务外化为可以在其他地方托管并通过更小,更简洁的界面进行通信的组件。实际上,除了图像处理,数学和科学应用之外,重型数据处理不会出现。

+0

我还会补充说,在将WCF类作为MVC模型公开时存在安全风险。 – VsMaX

+1

WCF在两者之间的想法是,MVC将仅用于演示。当页面上的字段被更新并保存时;该类将被填充并发送到WCF进行操作并保存到数据库。现在的问题是如果这是一个理想的方式来做到这一点。我们希望每个服务都负责数据库中的一组表,因此,如果数据添加/更新/删除,那么数据总是会流经这些服务。 – Will

+0

@听起来不错,在我看到内部WCF图层出现问题的情况下,它始终是由于该图层暴露的方法与它仅仅是一个程序集时一样多。通过精心设计WCF层,理论上它可以/应该起作用。你可能最终得到的是一个WCF层,它返回一个完整的集合(几乎是视图模型),它包含了在一次调用中显示特定页面所需的一切。这可以让以后轻松插入手机应用程序表示层。我只是留意WCF层之上的任何层的商业逻辑。 –

2

我们以您在当前雇主的帖子中描述的方式使用WCF。我们最终拥有用于WCF和MVC的DTO类与MVC应用程序进行通信,然后使用ViewModels进行UI内的模型绑定和验证。

我同意使用几乎彼此重复的类和它们之间的映射是一种痛苦,而且在某种程度上似乎是错误的。从我过去读过的内容看,我们做了什么,以及可能被迫做的事情是最佳做法。

Adrian上面提到的关于仅由WCF完成的重要处理的内容也很有意义。在开始我目前的工作之前,我就是这么做的。大多数业务逻辑被放置在由MVC应用程序直接引用的业务层组件中。对于少数可能长时间运行的进程,我创建了独立的WCF服务,以便与MVC应用程序进行通信。

最后,你可以使用Web API vs WCF吗? Web API是轻量级的,并且利用HTTP来消除WCF绑定带来的所有开销等。另外,使用Web API,您可以使用MVC应用程序使用的相同类,甚至可以在Web API中使用模型验证。这是我一直在努力并且变得越来越普遍的事情。

希望有帮助!

+0

感谢您的回应。映射重复类似乎对我来说也是错误的,但正如你所说,这似乎是最佳实践。直到现在,我还没有意识到WebAPI。不幸的是,我们的服务是TCP绑定,但WebAPI可能对我的其他项目有用。 – Will