0

我不知道这是否可以做到,但我有一个 WCF 服务应该返回一个自定义对象,该对象具有另一个包含流的自定义对象的集合。

当我尝试返回这个对象时,我得到了

System.Runtime.Serialization.InvalidDataContractException:无法序列化类型“System.ServiceModel.Dispatcher.StreamFormatter+MessageBodyStream”。考虑使用 DataContractAttribute 属性对其进行标记,并使用 DataMemberAttribute 属性标记您想要序列化的所有成员。有关其他支持的类型,请参阅 Microsoft .NET Framework 文档。

如果我更改为只返回一个以 Stream 作为返回类型的流的方法,它可以正常工作。我要发布的代码太多了,所以我只是想知道一般来说是否可能,如果有什么特别的事情我必须做一些特殊的事情才能让带有流的自定义对象从 WCF 服务返回而不会出现错误?

我现在在测试时使用 wsHttpBindig。

我已将流和 IList 标记为类中的 DataMembers,我应该将它们标记为其他内容吗?

感谢您的帮助,如果无法理解,我可以尝试创建一个小示例代码

4

3 回答 3

4

您真的希望流式传输发生,还是只想将其序列化(并且可以对其进行缓冲)?

如果您可以接受缓冲:

请记住,DataContractSerializer 没有对 Streams 的内置支持,但它支持字节数组。所以,做通常的 DataContract 类型转换技巧:不要用 DataMember 标记流,而是创建一个封装 Stream 的 byte[] 类型的私有 [DataMember] 属性。就像是:

public Stream myStream;

[DataMember(Name="myStream")]
private byte[] myStreamWrapper {
   get { /* convert myStream to byte[] here */ }
   set { /* convert byte[] to myStream here */ }
}

如果你真的想要它流式传输:

如果 Stream 是整个正文,则 WCF ServiceModel 只能支持流式消息正文。因此,您的操作应该返回一个 MessageContract,它将所有非 Stream 事物作为标头返回。像这样:

[MessageContract]
public class MyMessage {
   [MessageHeader]
   public MyDataContract someInfo;
   [MessageBody]
   public Stream myStream;
}
于 2009-10-09T07:45:25.613 回答
2

简而言之:您不能将缓冲传输(发回标记为 DataContracts 的 int、string 或自定义复杂类型)与流式传输混合。

这里有很好的记录:MSDN on WCF Streaming

它说:

流传输的限制

使用流传输模式会导致运行时强制执行附加限制。

流式传输中发生的操作最多可以与一个输入或输出参数签订合同。该参数对应于消息的整个主体,并且必须是 Message、Stream 的派生类型或 IXmlSerializable 实现。有一个操作的返回值相当于有一个输出参数。

因此,我想您必须重新构建您的解决方案以拥有两种方法 - 一种以复杂类型返回基本信息,另一种处理流式传输的操作。

马克

于 2009-10-09T08:21:43.457 回答
0

这似乎是一个重复的问题 - 请参阅我对WCF 返回自定义对象的回答,该对象包含一组自定义对象,其中包含解决方案的流。

顺便一提

当您在 [OperationContract] 中直接使用 Stream 时,这是一种特殊情况。DataContractSerializer 甚至没有被调用。WCF ServiceModel 使用一种特殊的方式使用流写出消息正文(如果底层绑定支持,则确保它实际上是流式传输的)。

但是,当您将 Stream 用作 [DataContract] 中的另一个 [DataMember] 时,它只是 DataContractSerializer 的另一种类型,并且不受支持。所以你必须使用类型转换技巧(见我之前的链接)。

不直观,我知道 :) 但在某种程度上记录了herehere

于 2009-10-09T07:53:21.930 回答