WCF - return object with stream data

Is it possible to return a stream that is part of a complex object as returned data from the Wcf method?

I checked most msdn links to stream saving data using Wcf; for example this one . All the examples seem to show how to return a stream when the type of the returned method is a stream (or a parameter is a stream).

I want to know if it can return a stream if the data is part of a complex property of an object? For example, GetData () may return data containing a stream, as shown below:

[DataContract] public class Data { [DataMember] public string Info { get; set; } /// <summary> /// This is the file stream that would be returned to client. /// </summary> [DataMember] public Stream File { get; set; } } [ServiceContract()] public interface IService { [OperationContract] Data GetData(); } 

From my initial testing, this seems to not work. I get a client side exception (unexpected socket closure). The result is the same regardless of DataContractSerialization or XmlSerialization. I set the required streaming mode using TransferMode.Streamed .

+4
source share
2 answers

You cannot do this, see this documentation.

At least one of the parameter and return value types must be either Stream, Message, or IXmlSerializable.

So, as you wrote it, it will not work for TransferMode.Streamed , however, nothing in this link explicitly says that a property of type Stream will not be serialized, but from experience I would not expect this to work.

Instead, you should return Stream and define the first x bytes as the field of your Info string.

  [ServiceContract()] public interface IService { [OperationContract] Stream GetData(); } 

so when writing to a stream (server side) you would do

  stream.Write(infoStr);//check size and truncate if appropriate stream.Write(fileBytes);//write your file here 

Then on the other hand, you need to read from correctly in order to get data from the stream. I would suggest writing 2 int to the stream first. The first will be the size of your infoStr field, and the second will be the size of your file. For the size of the client, you first read them, then you know how many bytes you need to read.

+2
source

you can use a contract with a message, develop your contract as

 [MessageContract] public class Data { [MessageHeader(MustUnderstand = true)] public string Info { get; set; } /// <summary> /// This is the file stream that would be returned to client. /// </summary> [MessageBodyMember(Order = 1)] public Stream File { get; set; } } [ServiceContract()] public interface IService { [OperationContract] Data GetData(); } 
+3
source

All Articles