[英]How do you return a user defined type from a WCF service?
我在IIS中托管了WCF服务。 目的是让客户进行调用并接收在另一个项目/ dll中定义的自定义类。 我使用svcutil.exe生成了一个服务客户端。 问题是这个自动生成的客户端包含我尝试从服务返回的类的新的部分/代理定义。 它现在在编译时抛出我的原始自定义类和新的部分定义之间的转换错误。 那么如何从WCF服务返回用户定义的类型? 建议表示赞赏。
如果要从服务调用返回的类型未标记为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()
的返回类型。
以下是使用DataContract
的示例:
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
在客户端应用程序中创建将被序列化并发送到WCF服务的代理类。
现在,如果要返回不是DataContract
的类型,则必须向客户端应用程序提供包含该类型的程序集的副本。
需要做的事情之一是用户必须配置服务引用以使用DLL中的类型而不是代理定义的类 - http://msdn.microsoft.com/en-us/library/ bb628653.aspx
我们过去曾沿着这条路走下去,问题当然是,这些是两个不同的类,所以你必须遵循@Rich Reuter提供的链接;
但是,我们已经了解了为什么这是不好的做法,因为它再次成为SOA的第三个原则 - “服务共享架构和合同,而不是类”。
当然问题不仅仅是不遵循某人在某个时候设定的“规则”,而是有充分的理由建议这一点 - 我们已经了解到服务与客户之间这种紧密耦合的代价意味着它很难释放 - 如果服务需要向该类添加另一个字段,为另一个客户端提供服务 - 第一个客户端可能会受到影响; 如果服务需要更改该类定义中的某些内容(以服务另一个客户端) - 第一个客户端将再次受到影响,反之亦然 - 客户端可能会影响服务的生命周期。
在大型项目中,这很快就会成为巨大的维护负担。
我以前走过这条路,并且在某些方面希望我没有。 可扩展性/自定义序列化 - 您必须非常小心。 如果使用预卷序列化程序(例如protobuf-net (可以直接集成到WCF中,并且设计时考虑了可扩展性),则会更容易一些,但并不容易。
实际上,共享类的一个优点是它使测试更容易:因为你到处都有相同的IFoo
,你可以用合理的成功机会模拟IFoo
。 当代理涉及时(当您在测试代码和生产代码之间更改更多移动部分时)更难模拟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.