none
请问 WCF DataContract 类,其 method 被客户端调用问题 RRS feed

  • 问题

  • 本帖已曾查了一堆书和资料,如:
    http://www.cnblogs.com/frank_xl/archive/2009/04/14/1433712.html
    ,并曾询问老徐大哥,但仍希望再询问网络上各大高手的意见。

    即使最后答案是无解,若各位网友愿提供不错的意见,即使只是一个有参考价值的 URL 或文章,本帖也会给分。

    ---------------------------------------------------------------------------------
    需求 :
    WCF Service 的「数据契约(Data Contract)」类,里面又有自定义的「方法」,希望这个方法,也能在网络传送后,能被客户端调用。

    ---------------------------------------------------------------------------------
    起因 :
    一位 Design Patterns 走火入魔的狂人,在一个 ASP.NET 小系统里,也搞了几百个自定义类。现在要把这个 ASP.NET App_Code 文件夹里许多里,能发布成 WCF Service。但有一个需求,如下 :

    //这是 WCF 服务器端,某个类的代码,返回一个自定义类 TradeTO 的实例,且此 TradeTO 类有属性也有「方法」
    public com.公司.vehicle.to.TradeTO calculate (com.公司.vehicle.to.TradeTO tradeTO)
    {
      com.公司.vehicle.sb.CalculatorSB.calculateMoney (tradeTO);
      return tradeTO;
    }
    

    TradeTO 类的实例,希望能在 WCF 中被传输。此类已在 Server-side 被标示为 [DataContract],但由于成员标示 [DataMember] 只适用于 Property、Field,不适用于 Method。导致返回 WCF client-side 的 TradeTO 类的实例,在客户端,会调用不到其 方法: Method1(),如下 :

    using System.Runtime.Serialization;
    using System.ServiceModel;
    
    [DataContract]
    public class TradeTO
    {
      [DataMember]
      public string strName = "吴小弟";
    
      [DataMember]
      public string StrName { get; set; }
    
      // 这个 Method1 方法,在客户端无法调用 (此为本帖目前的问题所在)
      public string Method1()
      {
        return "this is Method1...";
      }
    }
    


    我试过其他的做法,例如把 Method1() 标示为 [OperationContract],也把 TradeTO 类标示为 [ServiceContract],并将该类发布为 WCF 服务,如下 :

    using System.Runtime.Serialization;
    using System.ServiceModel;
    
    [DataContract]
    [ServiceContract]
    public class TradeTO
    {
      [DataMember]
      public string strName = "吴小弟";
    
      [DataMember]
      public string StrName { get; set; }
    
      // 这个 Method1 方法,在客户端无法调用 (此为本帖目前的问题所在)
      [OperationContract]
      public string Method1()
      {
        return "this is Method1...";
      }
    }
    

    虽然编译无误。但结果都一样,无效,客户端就是无法在返回的 TradeTO 里 :
    public com.tfmi.vehicle.to.TradeTO calculate (com.tfmi.vehicle.to.TradeTO tradeTO)

    找到、调用这个 TradeTO 实例的方法,只能找到它的 Property、Field (标示为 [DataMember] 的成员)

    ---------------------------------------------------------------------------------

    虽然知道这是 .NET WebService、WCF 的默认行为,但仍想请教,有无其他解决方案?或有其他高手有独特的见解。
    先谢谢各位。
    ---------------------------------------------------------------------------------

     

     

    • 已编辑 吳浩然 2010年10月31日 7:46 用 Firefox 重编辑排版乱掉
    2010年10月31日 7:29

答案

  • 一种解决办法,是把datacontract独立放到一个ClassLibrary project里,然后让服务端和客户端都引用它。客户端添加服务时,勾上 "Reuse types in all referenced assemblies". 这样,客户端就可以使用方法了。

    一个前提是,datacontract方法不能对外部存在依赖,比如方法中使用HttpContext。


    Mog Liang
    • 已标记为答案 Mog Liang 2010年11月5日 9:53
    2010年11月3日 1:18

全部回复

  • 你好!首先小弟用了wcf几年了还没有试过仁兄这样直接在datacontract中写方法。这觉得这样做有点不可思议。因为datacontract是要被序列化和反序列化的对象。如果它里这有像方法这样的逻辑代码。那它真的能被序列化吗?会不会是仁兄对面向服务设计思想上走到了一个错误的方向。以上纯属小弟遇见。请仁兄多多包含!
    2010年10月31日 16:50
  • 在他们 java/OO/Desgin Patterns 的世界,貌似常有这种设计,
    只是当初没想到要把这些 Class 都挂到 WCF 上。

    这阵子查资料,WCF 默认也不支持这种设计。

    http://topic.csdn.net/u/20101031/15/b7b7625f-cdfc-4bb7-9594-1be6f937ccae.html

     


    Wizard 编程网 - 博客园
    2010年11月1日 1:03
  • 从理论上来讲应该是不支持的。因为这不是oo,这是soa,所以设计方式是和oo有挺大差别的,因为oop只适用于内部代码的设计模上,而soa是面向用户的。从这点不难想到他们设计上的差异性还是挺大的。
    2010年11月1日 4:31
  • 一种解决办法,是把datacontract独立放到一个ClassLibrary project里,然后让服务端和客户端都引用它。客户端添加服务时,勾上 "Reuse types in all referenced assemblies". 这样,客户端就可以使用方法了。

    一个前提是,datacontract方法不能对外部存在依赖,比如方法中使用HttpContext。


    Mog Liang
    • 已标记为答案 Mog Liang 2010年11月5日 9:53
    2010年11月3日 1:18
  • thanks. 今天才发现您的回复。
    Wizard 编程网 - 博客园
    2010年11月7日 6:27