WCF返回一个自定义对象,其中包含一组包含流的自定义对象

时间:2009-10-09 07:35:16

标签: wcf stream return-value collections custom-object

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

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

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

如果我改为使用Stream返回其中一个流作为返回类型的方法,它可以正常工作。我发布的代码太多了,所以我只是想知道它是否可能,如果有一些特殊的东西,我必须做的是获得带有流的自定义对象,而不会出现WCF服务的错误?

我在测试时使用wsHttpBindig。

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

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

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:2)

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

这里有详细记录:MSDN on WCF Streaming

它说:

  

流式传输的限制

     

使用流式传输模式   导致运行时间强制执行   其他限制。

     

跨越的发生的操作   流式运输可以签订合同   最多一个输入或输出   参数即可。该参数对应   对整个信息和   必须是Message,派生类型   流,或IXmlSerializable   实现。有返回值   对于一个操作相当于   有一个输出参数。

所以我猜你必须重新构建你的解决方案才能有两个方法 - 一个返回复杂类型的基本信息,另一个方法处理流媒体。

马克

答案 2 :(得分:0)

这似乎是一个重复的问题 - 请参阅我对WCF returning a custom object with a collection of custom objects containing streams的解答。

顺便说一下

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

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

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