0

I have a WCF service that needs to send files and an xml \ SOAP message to the caller. In this instance the calling object is SOAP UI.

I have tried returning the object as a byte array which gets encoded as a base64 string and then is not recognised as an attachment.

So I am trying to use a stream to send the files using the following example found here C# multipart response building

This appears to work in part, however, the pdf file(s) that come down do not come as an attachment, however appear to be part of the message as per the image below.

enter image description here

the code is

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

}

As you can see in this example im just pushing a single file down as i was wondering if something else is getting in its way, however this is still the same result.

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

I have also tried transferMode in each of the options and no joy either. I would be grateful for any and all help in how to resolve this

Simon Price
  • 3,011
  • 3
  • 34
  • 98
  • MTOM is a mechanism for transmitting large binary attachments with SOAP messages as raw bytes. If the amount of data transmitted is too small, MTOM will not be used even if MTOM is set. – Ding Peng Jun 24 '20 at 08:47
  • I have tried MTOM as my first port of call, that didnt work, I have also tried sending byte arrays as part of an object which then get sent as base64 string, but I need to send the actual files as attachments rather than a string object they transform back – Simon Price Jun 24 '20 at 08:48
  • Can you successfully call through WCF client-side? – Ding Peng Jun 24 '20 at 08:51
  • Using SOAP UI as the client for the time being we can successfully call through, and get the SOAP Message out, however, with the files that are needed, they also come through in as you see in the question above the message rather than coming down as an attachment – Simon Price Jun 24 '20 at 08:55
  • I see a lot of garbled code in soap UI. I think it may be that soap UI cannot parse SOAP messages sent by WCF Server. – Ding Peng Jun 24 '20 at 09:07
  • Looking at the service that we are replacing (that we do not have production code for) soap ui shows me I have 10 attachments. returning the files as I am trying to right now, I see 0 – Simon Price Jun 24 '20 at 09:34
  • You can refer to this link, which contains information on how to send attachments in WCF:https://social.msdn.microsoft.com/Forums/en-US/a5eb53b4-c903-4b18-8ab0-cdb575305fcd/injectsend-attachmentsany-file-with-request-in-wcf?forum=wcf – Ding Peng Jul 02 '20 at 06:36
  • @Dingpeng I have seen a number of these and they just get sent back as a base64 Encoded string – Simon Price Jul 02 '20 at 09:18

0 Answers0