I have already return zip file stream to client as the following MessageContract
:
[MessageContract]
public class ExportResult_C
{
[MessageHe
I want to share the result of my investigation and my solution to pass big file as stream to client consumer:
Question 1:
this is not possible to have MessageBodyMember
دeither Stream
or any other type, after running code you may got an Exception as following:
In order to use Streams with the MessageContract programming model, the type yourMessageContract must have a single member with MessageBodyMember attribute and the member type must be Stream.
Question 2:
I changed the contract to have a prop member named Stream
like what I was wanted, the Streams
is array of stream:
[MessageBodyMember]
public Stream[] Streams
{
get;
set;
}
my piece of code to split big file to parts of zip and make stream of each part into Streams
like:
ZipFile zip = new ZipFile();
if (!Directory.Exists(zipRoot))
Directory.CreateDirectory(zipRoot);
zip.AddDirectory(packageSpec.FolderPath, zipRoot);
zip.MaxOutputSegmentSize = 200 * 1024 * 1024; // 200 MB segments
zip.Save(fileName);
ExportResult_C result = null;
if (zip.NumberOfSegmentsForMostRecentSave > 1)
{
result = new ExportResult_C()
{
PackedStudy = packed.ToArray(),
Streams = new Stream[zip.NumberOfSegmentsForMostRecentSave]
};
string[] zipFiles = Directory.GetFiles(zipRoot);
foreach (string fileN in zipFiles)
{
Stream streamToAdd = new MemoryStream(File.ReadAllBytes(fileN));
result.Streams[zipFiles.ToList().IndexOf(fileN)] = streamToAdd;
}
}
else
{
result = new ExportResult_C()
{
PackedStudy = packed.ToArray(),
Streams = new Stream[1] { new MemoryStream(File.ReadAllBytes(fileName)) }
};
}
return result;
At the compile time there is no any error when we have array of stream in MessageBodyMember
, everything works fine until the service is passing array stream (result
in code) to consumer at runtime, by the way I cross the Exception like :
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:29:59.9895560'.
Question 3:
To implement the mentioned scenario the Contract
should not change for Backward-Compatibility so the contract have a message body stream like before:
[MessageBodyMember]
public Stream Stream
{
get;
set;
}
but I am going to write stream of the zip part to end of Stream
as one stream and in client-server will be read an split each stream as file
solution:
4 Byte for length number of each stream
each stream content write after it's length number(after 4 byte)
at the end stream will be something like this
Stream = Part1 len + part1 stream content + part2 len + part2 stream content + ....
any comment and help around the answer would be truly appreciated.