您的示例将无法编译,因为接口不能包含字段,即 ObjectID、StringOne 和 StringTwo。您尝试使用 IObject、IOne 和 ITwo 定义的是数据合同,而不是服务合同。因此,您应该使用 DataContract 属性,而不是 ServiceContract 属性和类,而不是接口。
[DataContract]
[KnownType(typeof(MyOne))]
[KnownType(typeof(MyTwo))]
public class MyObject
{
[DataMember]
Guid ObjectID;
}
[DataContract]
public class MyOne : MyObject
{
[DataMember]
String StringOne;
}
[DataContract]
public class MyTwo : MyObject
{
[DataMember]
String StringTwo;
}
请注意,这些是类,而不是接口。 DataContract 属性已替换 ServiceContract 属性。 KnownType 属性已替换 ServiceKnownType 属性。从我所看到的来看,这更规范。
您的服务合同将被定义如下:
[ServiceContract]
public interface IConnection
{
[OperationContract]
[ServiceKnownType(typeof(MyOne))]
[ServiceKnownType(typeof(MyTwo))]
MyObject RetrieveObject(Guid ObjectID);
[OperationContract]
[ServiceKnownType(typeof(MyOne))]
[ServiceKnownType(typeof(MyTwo))]
Guid StoreObject(MyObject NewObject);
}
您可以将 ServiceKnownType 属性放在合同级别(即,在 ServiceContract 属性下方),以使其适用于合同的所有操作。
[ServiceContract]
[ServiceKnownType(typeof(MyOne))]
[ServiceKnownType(typeof(MyTwo))]
public interface IConnection
{
[OperationContract]
MyObject RetrieveObject(Guid ObjectID);
[OperationContract]
Guid StoreObject(MyObject NewObject);
}
您可以在数据合同中使用如下接口:
interface IEmployee
{
string FirstName
{ get; set; }
string LastName
{ get; set; }
}
[DataContact]
class Employee : IEmployee
{...}
但是,导出的元数据中不包含 IEmployee 接口。因此,如果您使用 svcutil 生成代理类,您的客户将不会知道 IEmployee。如果您的服务和客户端驻留在同一个应用程序中,这没什么大不了的(这是在应用程序域之间进行通信的好方法)。但是,如果您的客户端与您的服务是分开的(在绝大多数情况下,它将是),这将成为问题,因为您必须在客户端手动复制 IEmployee 接口。