首页 > 解决方案 > WCF - 内存流未正确发送文件\流

问题描述

我有一个 WCF 服务,需要向调用者发送文件和 xml \ SOAP 消息。在本例中,调用对象是 SOAP UI。

我尝试将对象作为字节数组返回,该数组被编码为 base64 字符串,然后不被识别为附件。

所以我尝试使用流来发送文件,使用以下示例在此处找到C# multipart response building

这似乎部分起作用,但是,下来的 pdf 文件不是作为附件出现,而是根据下图似乎是消息的一部分。

在此处输入图像描述

代码是

[WebMethod]
public getProposalResponse getProposal(getProposalRequest request)
{
    if (request == null)
    {
        // Throw fault exception
        ErrorResponseHelper.MalformedResponse();
    }
    var privateKey = _privateKeyService.GetPrivateKey();

    var response = _getProposalService.GetProposal(request.getProposal);

    var fileByteArray = _blobStorageService.DownloadProposalsAsByteArray(response.Proposal.FileAttachments).ToArray();
    var FileStream = _blobStorageService.DownloadProposalsAsStream(response.Proposal.FileAttachments);
    response.Proposal.Attachments = fileByteArray;

    var context = HttpContext.Current;
    sendFiles(context, fileByteArray);

    return response;
}

private void WriteFilePart(HttpContext context, byte[] fileBytes, string FileName, byte[] boundarybytes, Stream memStream)
{

    string Tosend = "";
    Tosend = Tosend + "Content-Type: " + "application/pdf" + "" + Environment.NewLine;
    Tosend = Tosend + "Content-Location: " + FileName + "" + Environment.NewLine;
    Tosend = Tosend + "Content-Disposition: attachment; filename=\"" + FileName + "\"" + Environment.NewLine;
    Tosend = Tosend + "Content-ID: " + FileName + "" + Environment.NewLine;
    Tosend = Tosend + Environment.NewLine;

    memStream.Write(boundarybytes, 0, boundarybytes.Length);
    var headerbytes = System.Text.Encoding.UTF8.GetBytes(Tosend);
    memStream.Write(headerbytes, 0, headerbytes.Length);

    memStream.Write(fileBytes, 0, fileBytes.Length);


}

private void sendFiles(HttpContext context, byte[][] fileByteArray)
{
    context.Response.Clear();
    context.Response.StatusCode = (int)HttpStatusCode.OK;

    string formDataBoundary = String.Format("----------{0:N}", DateTime.Now.Ticks.ToString("x"));
    context.Response.ContentType = "multipart/form-data; boundary=" + formDataBoundary;
    context.Response.ContentEncoding = System.Text.Encoding.UTF8;

    context.Response.Headers.Add("X-data", "21-08-2017");
    context.Response.Headers.Add("X-numberfiles", "21");
    context.Response.Headers.Add("X-Id", "45625625EFA22AD");

    Stream memStream = new MemoryStream();
    var boundarybytes = System.Text.Encoding.UTF8.GetBytes("--" + formDataBoundary + "\r\n");
    var endBoundaryBytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + formDataBoundary + "--");
    var i = 0;
    //foreach (var FileName in fileByteArray)
    //{
    //    WriteFilePart(context, FileName, $"simon-{i++}.pdf", boundarybytes, memStream);
    //    boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + formDataBoundary + "\r\n");
    //}

    WriteFilePart(context, fileByteArray[0], $"simon-{i++}.pdf", boundarybytes, memStream);
    boundarybytes = System.Text.Encoding.UTF8.GetBytes("\r\n--" + formDataBoundary + "\r\n");

    memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);

    using (Stream ResponseStream = context.Response.OutputStream)
    {
        memStream.Position = 0;
        byte[] tempBuffer = new byte[memStream.Length];
        memStream.Read(tempBuffer, 0, tempBuffer.Length);
        memStream.Close();
        ResponseStream.Write(tempBuffer, 0, tempBuffer.Length);
    }

}

正如您在此示例中看到的那样,我只是将单个文件向下推,因为我想知道是否有其他东西妨碍了它,但这仍然是相同的结果。

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="basic" messageEncoding="Mtom" maxReceivedMessageSize="700000" transferMode="Buffered">
      <readerQuotas maxArrayLength="700000"/>
    </binding>
  </basicHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>    
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
</system.serviceModel>

我也在每个选项中都尝试过 transferMode ,也没有任何乐趣。对于如何解决此问题,我将不胜感激

标签: c#.netwcfsoapmemorystream

解决方案


推荐阅读