I have a WCF service that returns a stream object. But for some reason i get a corrupt zip file back which i am streaming. All the code is below Please advise
Contract Code
[ServiceContract(Namespace = "http://schemas.acme.it/2009/04/01")]
public interface IFileTransferService
{
[OperationContract(IsOneWay = false)]
FileDownloadReturnMessage DownloadFile(FileDownloadMessage request);
[OperationContract()]
string HellowWorld(string name);
}
[MessageContract]
public class FileDownloadMessage
{
[MessageHeader(MustUnderstand = true)]
public FileMetaData FileMetaData;
}
[MessageContract]
public class FileDownloadReturnMessage
{
public FileDownloadReturnMessage(FileMetaData metaData, Stream stream)
{
this.DownloadedFileMetadata = metaData;
this.FileByteStream = stream;
}
[MessageHeader(MustUnderstand = true)]
public FileMetaData DownloadedFileMetadata;
[MessageBodyMember(Order = 1)]
public Stream FileByteStream;
}
[DataContract(Namespace = "http://schemas.acme.it/2009/04/01")]
public class FileMetaData
{
public FileMetaData(string [] productIDs, string authenticationKey)
{
this.ids = productIDs;
this.authenticationKey= authenticationKey;
}
[DataMember(Name = "ProductIDsArray", Order = 1, IsRequired = true)]
public string[] ids;
[DataMember(Name = "AuthenticationKey", Order = 2, IsRequired = true)]
public string authenticationKey;
}
SVC file code
public class DownloadCoverScan : IFileTransferService
{
public FileDownloadReturnMessage DownloadFile(FileDownloadMessage request)
{
FileStream stream = new FileStream(@"C:\Pictures.zip", FileMode.Open,
FileAccess.Read);
FileMetaData metaData= new FileMetaData(new string[] { "1", "2" },"asd");
FileDownloadReturnMessage returnMessage =
new FileDownloadReturnMessage(metaData,stream);
return returnMessage;
}
public string HellowWorld(string name)
{
return "Hello " + name;
}
}
Config code
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="DownloadCoverScanBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="DownloadCoverScanBehavior" name="DownloadService.DownloadCoverScan">
<endpoint address="" name="basicHttpStream" binding="basicHttpBinding" bindingConfiguration="httpLargeMessageStream"
contract="DownloadService.IFileTransferService" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="httpLargeMessageStream" maxReceivedMessageSize="2147483647" transferMode="Streamed" messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
</system.serviceModel>
Client Code
FileMetaData metaData = new FileMetaData();
metaData.ProductIDsArray = new string[] { "1", "2" };
metaData.AuthenticationKey = "test";
FileDownloadMessage inputParam = new FileDownloadMessage(metaData);
FileTransferServiceClient obj = new FileTransferServiceClient();
FileDownloadReturnMessage outputMessage = obj.DownloadFile(inputParam);
Byte[] buffer = new Byte[8192];
int byteRead = outputMessage.FileByteStream.Read(buffer, 0, buffer.Length);
Response.Buffer = false;
Response.ContentType = "application/zip";
Response.AppendHeader("content-length", buffer.Length.ToString());
Response.AddHeader("Content-disposition", "attachment; filename=testFile.zip");
Stream outStream = Response.OutputStream;
while (byteRead > 0)
{
outStream.Write(buffer, 0, byteRead);
byteRead = outputMessage.FileByteStream.Read(buffer, 0, buffer.Length);
}
outputMessage.FileByteStream.Close();
outStream.Close();
I think the problem may be the
Content-Lengthheader from the response. You set it to 8192 while you actually don’t know the length yet.I’m not absolutely sure, however. Maybe it goes wrong earlier in the process. Maybe you can put some logging statement in your client code to be sure that you actually write all bytes to the output stream (by logging
byteReadfor example).