2010-08-31 31 views
2

我有一个WCF服务返回一个流对象。但由于某种原因,我收到了一个损坏的zip文件,我正在流式传输。所有的代码如下,请告知WCF服务流字节数组大小问题

合约代码

[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文件代码

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; 
     } 

    } 

配置代码

<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> 

客户端代码

 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(); 

回答

4

缓冲区的大小没多大关系,随便挑一个合理的规模,如:

Byte[] buffer = new Byte[8192]; 

也有在你的代码,你写缓冲区的内容的错误:

outStream.Write(buffer, 0, buffer.Length); 

应该是:

outStream.Write(buffer, 0, byteRead); 

否则你将永远写,即使它只是部分填满数据的整个缓冲区。

+0

感谢您的回复, 我已经根据建议进行了更改,我可以看到我能够下载我的zip文件,但是当我解压缩它时,则出现错误。所以不知道错误是在哪里,他在WCF服务或客户端。我用所有的代码更新了我的问题。请告知 – Amit 2010-08-31 07:27:27

+0

@Amit:问题在于您将内容长度设置为缓冲区大小。如果你能找出实际的流大小,你可以使用它,否则你必须跳过content-length属性。 – Guffa 2010-08-31 07:52:55

+0

好的,我会做出改变。谢谢 – Amit 2010-08-31 09:12:04