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