我不知道是否可以这样做,但是我有一个应该返回自定义对象的WCF服务,该对象有另一个包含流的自定义对象的集合。
当我尝试返回此对象时,我得到了
System.Runtime.Serialization.InvalidDataContractException:类型'System.ServiceModel.Dispatcher.StreamFormatter + MessageBodyStream'无法序列化。请考虑使用DataContractAttribute属性对其进行标记,并使用DataMemberAttribute属性标记要序列化的所有成员。有关其他受支持的类型,请参阅Microsoft .NET Framework文档。
如果我改为使用Stream返回其中一个流作为返回类型的方法,它可以正常工作。我发布的代码太多了,所以我只是想知道它是否可能,如果有一些特殊的东西,我必须做的是获得带有流的自定义对象,而不会出现WCF服务的错误?
我在测试时使用wsHttpBindig。
我已经在类中标记了流和IList作为DataMembers,我应该将它们标记为其他内容吗?
感谢您的帮助,如果不可理解,我可以尝试创建一个小示例代码
答案 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的另一种类型,而且是一个不受支持的类型。所以你必须使用类型转换技巧(参见我之前的链接)。