代码之家  ›  专栏  ›  技术社区  ›  flesh

如何从WCF服务返回用户定义的类型?

  •  7
  • flesh  · 技术社区  · 17 年前

    我在IIS中托管了一个WCF服务。其目的是让客户端调用并接收在另一个项目/dll中定义的自定义类。我已经使用svcutil.exe生成了一个服务客户端。问题是这个自动生成的客户机包含我试图从服务返回的类的新部分/代理定义。现在,它在编译时在我的原始自定义类和新的部分定义之间抛出一个转换错误。那么,如何从WCF服务返回用户定义的类型呢?谢谢你的建议。

    4 回复  |  直到 17 年前
        1
  •  10
  •   Andrew Hare    17 年前

    如果要从服务呼叫返回的类型未标记为 DataContract 如果不向客户端应用程序提供同一程序集的副本,您将无法从WCF返回它。

    using System;
    using System.ServiceModel;
    
    [ServiceContract]
    interface IService
    {
        [OperationContract]
        TimeSpan GetTimeSpan();
    }
    
    class Service : IService
    {
        public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
    }
    

    那么为什么前面的代码可以工作呢?它之所以有效,是因为服务调用的双方都有 System.dll System.TimeSpan 类型,它是OperationContract的返回类型 GetTimeSpan() .

    数据合同 :

    using System;
    using System.ServiceModel;
    using System.Runtime.Serialization;
    
    [ServiceContract]
    interface IService
    {
        [OperationContract]
        Contract GetContract();
    }
    
    [DataContract]
    class Contract
    {
        [DataMember]
        public String MyProperty { get; set; }
    }
    
    class Service : IService
    {
        public Contract GetContract() { return new Contract(); }
    }
    

    现在,您已经为已定义的类提供了序列化属性( Contract )-这将允许您使用 svcutil.exe

    现在,如果要返回一个不是 数据合同

        2
  •  4
  •   Rich Reuter    17 年前

    需要发生的事情之一是,用户必须配置服务引用以使用DLL中的类型,而不是代理定义的类- http://msdn.microsoft.com/en-us/library/bb628653.aspx

        3
  •  4
  •   Yossi Dahan    17 年前

    我们过去曾走过这条路,问题是,当然,这是两个不同的类,所以你必须遵循@Rich Reuter提供的链接;

    当然,问题不仅仅是没有遵循某个人在某个时候设定的“规则”,而是有很多理由建议这样做——我们已经了解到,服务和客户机之间如此紧密耦合的代价意味着很难发布任何一个字段——如果服务需要向该类添加另一个字段,为另一个客户提供服务-第一个客户可能会受到影响;如果服务需要更改该类定义中的某些内容(以服务另一个客户端),则第一个客户端将再次受到影响,反之亦然,客户端可能会影响服务的生命周期。

    在大型项目中,这很快成为一个巨大的维护负担。

        4
  •  4
  •   Community Mohan Dere    8 年前

    只差一秒 Yossi's / Rich's

    • 是的,它破坏了很多数据契约的意图,如果发生任何类型的自定义序列化,扩展服务时可能会遇到问题

    我以前也走过这条路,在某些方面我希望我没有。可重新扩展性/自定义序列化-您必须 非常 protobuf-net

    事实上,一个 有利条件 IFoo 在任何地方,你都可以嘲笑这一点