我在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成员,因此其余属性必须位于标头中。

10-04 12:06