Search code examples
c#streamhttpclientazure-logic-apps

Using HttpClient to POST files to Azure logic app -- but resulting email attachment is always corrupted


I have a logic app that has an HTTP POST request as a trigger (I haven't set up a schema or sample payload on that end). The logic app then sends an email with an attachment, which should be the first item in a multipart/form-data upload.

Code from my console application:

var form = new MultipartFormDataContent();
 
var bytes = ExcelBuilder.SaveData()

var fileContent = new ByteArrayContent(bytes, 0, bytes.Length);

fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
fileContent.Headers.Add("Content-Disposition", $"form-data; name=\"test\"; filename=\"test.xlsx\"");

form.Add(fileContent, "test", "test.xlsx")

var response = await httpClient.PostAsync(logicAppUri, form)

Code from my method which creates the byte array (using ClosedXML):

public byte[] SaveData()
{
   IXLWorkbook workbook = new XLWorkbook();

   var stream = new MemoryStream();
   workbook.SaveAs(stream)
   stream.Position = 0;

   return stream.ToArray();
}

Things I tried:

  1. Everything functions fine when I used hardcoded file paths, call workbook.SaveAs(string path), and then call File.ReadAllBytes(string path). and finally saved that to a ByteArrayContent. I get a readable Excel file as an attachment.
  2. Reading the MemoryStream only (no .ToArray(), and with Position set to 0 before the return), passig that stream into a StreamContent constructor, and leaving everything else the same does not help. The attachment still ends up unreadable and corrupted.
  3. The stream is still readable in the console by ClosedXML. I am able to create and read a new Workbook with it in my main class. The data stays the same also.
  4. Using Path.GetTempPath + "test.xlsx" and using a FileStream on that location also results in a corruped attachment.

The email itself is sending fine, no errors are being thrown, and the HTTP Post outputs in the logic app are pretty much the same. The $content part of the request is not empty either, actually they have pretty much the same content, except in the corrupted version there are some characters that are different (e.g. the $content is UAAAAI34IANFJDJF... in the readable runs, but UAAAAJ25IANFJFJF... in the unreadable runs). The attachments themselves are the same size and have the same name. It's just that the unreadable version can't be opened in Excel

I'm not supposed to save the Excel files locally, so I was using streams. Will a local save be the only way I'll be able to do this? This is my first time working with streams, so I'm suspecting that I'm doing something wrong there but I'm not too sure, I keep running into dead ends. Any advice would be greatly appreciated!


Solution

  • Figured it out! Misspelled the xlsx extension in my code (when adding to MultipartFormDataContent) and that was throwing everything off. Now it's working perfectly :)