我在wcf Contracts中使用了Stream
对象,因此被迫使用MessageContract
而不是DataContract
。
[MessageContract]
public class Document
{
[MessageBodyMember(Order = 1)]
public System.IO.Stream FileData;
}
[MessageContract]
public class A : Document
{
[MessageBodyMember]
public string input;
}
[MessageContract]
public class B : Document
{
[MessageBodyMember]
public string someProp;
}
[ServiceContract]
public interface ISomeService
{
[OperationContract]
Document SomeMethod(Document file);
}
我希望该服务的使用者创建A或B的对象,并使用它来调用服务。在服务方面,我可以将其类型转换为适当的对象,然后执行一些操作。
问题是我无法使用
KnownType
指定MessageContract
,并且继承的合同在服务中使用或用KnownType
声明之前无法公开给客户端。我尝试了google,但找不到与
KnownType
相关的MessageContract
的任何内容。如评论中所建议...我用
KnownType
更新了我的消息合同,但它们仍未通过服务参考向客户端公开...[MessageContract]
[KnownType(typeof(FileSystemStoredDocument))]
[KnownType(typeof(FileBoundStoredDocument))]
[KnownType(typeof(SharepointStoredDocument))]
public class Document : DocumentInfo, IDisposable
{
}
有人可以帮我这里有什么问题吗?
注意:所有
KnownType
都继承自Document
最佳答案
消息契约准确描述了消息的外观。它们确实支持继承,但是您必须指定在特定操作中使用的确切消息约定。
如果您检查邮件的正文部分:
ContractDescription.GetContract(typeof(ISomeService)).Operations[0].Messages[0].Body.Parts
您将只看到一个部分-
Stream
对象。这与数据协定相反,在数据协定中,主体包含一部分Object
类型。因此,您了解了为什么 KnownType
在这里不起作用。(除其他外,
ContractDescription
类用于生成WSDL。请参见WsdlExporter
类。)您可以做的是创建数据合同的层次结构,该层次结构将包含在消息合同中,例如
[MessageContract]
public class Document
{
[MessageHeader]
public DocumentProperties Properties;
[MessageBodyMember(Order = 1)]
public System.IO.Stream FileData;
}
[DataContract]
[KnownType(typeof(A))]
[KnownType(typeof(B))]
public abstract class DocumentProperties { }
[DataContract]
public class A : DocumentProperties
{
[DataMember]
public string input;
}
[DataContract]
public class B : DocumentProperties
{
[DataMember]
public string someProp;
}
请注意,如果要传递
Stream
,则不能有多个body成员,因此其余属性必须位于标头中。