R – WCF returning a custom object with a collection of custom objects containing streams

collectionscustom-objectreturn-valuestreamwcf

I don't know if this could be done, but I have a WCF service that should return a custom object, the object has a collection of another custom object that contains a stream.

when I try to return this object I get

System.Runtime.Serialization.InvalidDataContractException: Type 'System.ServiceModel.Dispatcher.StreamFormatter+MessageBodyStream' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

If I change to method to just return one of the stream with Stream as return type it works fine. It would be too much code for me to post, so I was just wondering in general if it's possible, and if there is somethings special I have to do to get custom object with streams to return without errors from WCF service?

I Use wsHttpBindig now while testing.

I have marked the streams and the IList as DataMembers in the classes, should I mark them something else?

Thanks for any help, if it's not understandable I can try to create a smal example code

Best Answer

Do you actually want streaming to happen, or do you just want it serialized (and are ok with it being buffered)?

If you're ok with it being buffered:

Keep in mind that the DataContractSerializer does not have built-in support for Streams, but it does for byte arrays. So, do the usual DataContract type conversion trick: Don't mark the stream with DataMember, but create a private [DataMember] property of type byte[] that wraps the Stream. Something like:

public Stream myStream;

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

If you actually want it streamed:

The WCF ServiceModel can only support a streamed message body if the Stream is the entire body. So, your operation should return a MessageContract that returns all the non-Stream things as headers. Like so:

[MessageContract]
public class MyMessage {
   [MessageHeader]
   public MyDataContract someInfo;
   [MessageBody]
   public Stream myStream;
}
Related Topic