使用 HttpClient 将 POST 文件发送到 Azure 逻辑应用程序——但生成的电子邮件附件始终已损坏
Using HttpClient to POST files to Azure logic app -- but resulting email attachment is always corrupted
我有一个逻辑应用程序,它有一个 HTTP POST 请求作为触发器(我还没有为此设置架构或示例负载)。然后,逻辑应用会发送一封带有附件的电子邮件,该附件应该是 multipart/form-data 上传中的第一项。
来自我的控制台应用程序的代码:
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)
我创建字节数组的方法中的代码(使用 ClosedXML):
public byte[] SaveData()
{
IXLWorkbook workbook = new XLWorkbook();
var stream = new MemoryStream();
workbook.SaveAs(stream)
stream.Position = 0;
return stream.ToArray();
}
我尝试过的事情:
- 当我使用硬编码文件路径、调用 workbook.SaveAs(string path),然后调用 File.ReadAllBytes(string path) 时一切正常。最后将其保存到 ByteArrayContent。我得到一个可读的 Excel 文件作为附件。
- 仅读取 MemoryStream(没有 .ToArray(),并且在 return 之前将 Position 设置为 0),将该流传递给 StreamContent 构造函数,并让其他所有内容保持不变并没有帮助。附件仍然无法读取和损坏。
- ClosedXML 在控制台中仍然可以读取该流。我可以在我的主 class 中使用它创建和阅读新的工作簿。数据也保持不变。
- 使用 Path.GetTempPath + "test.xlsx" 并在该位置使用 FileStream 也会导致附件损坏。
电子邮件本身发送正常,未抛出任何错误,并且逻辑应用中的 HTTP Post 输出几乎相同。请求的 $content 部分也不为空,实际上它们具有几乎相同的内容,除了在损坏的版本中有一些不同的字符(例如 $content 是 UAAAAAI34IANFJDJF ...在可读运行中,但 UAAAAJ25IANFJFJF ...在不可读的运行中)。附件本身大小相同,名称相同。只是无法阅读的版本无法在Excel
中打开
我不应该在本地保存 Excel 文件,所以我使用的是流。本地保存是我能够做到这一点的唯一方式吗?这是我第一次使用流,所以我怀疑我在那里做错了什么但我不太确定,我让 运行 陷入死胡同。任何建议将不胜感激!
想通了!在我的代码中拼错了 xlsx 扩展名(当添加到 MultipartFormDataContent 时),这导致所有内容都消失了。现在它运行完美:)
我有一个逻辑应用程序,它有一个 HTTP POST 请求作为触发器(我还没有为此设置架构或示例负载)。然后,逻辑应用会发送一封带有附件的电子邮件,该附件应该是 multipart/form-data 上传中的第一项。
来自我的控制台应用程序的代码:
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)
我创建字节数组的方法中的代码(使用 ClosedXML):
public byte[] SaveData()
{
IXLWorkbook workbook = new XLWorkbook();
var stream = new MemoryStream();
workbook.SaveAs(stream)
stream.Position = 0;
return stream.ToArray();
}
我尝试过的事情:
- 当我使用硬编码文件路径、调用 workbook.SaveAs(string path),然后调用 File.ReadAllBytes(string path) 时一切正常。最后将其保存到 ByteArrayContent。我得到一个可读的 Excel 文件作为附件。
- 仅读取 MemoryStream(没有 .ToArray(),并且在 return 之前将 Position 设置为 0),将该流传递给 StreamContent 构造函数,并让其他所有内容保持不变并没有帮助。附件仍然无法读取和损坏。
- ClosedXML 在控制台中仍然可以读取该流。我可以在我的主 class 中使用它创建和阅读新的工作簿。数据也保持不变。
- 使用 Path.GetTempPath + "test.xlsx" 并在该位置使用 FileStream 也会导致附件损坏。
电子邮件本身发送正常,未抛出任何错误,并且逻辑应用中的 HTTP Post 输出几乎相同。请求的 $content 部分也不为空,实际上它们具有几乎相同的内容,除了在损坏的版本中有一些不同的字符(例如 $content 是 UAAAAAI34IANFJDJF ...在可读运行中,但 UAAAAJ25IANFJFJF ...在不可读的运行中)。附件本身大小相同,名称相同。只是无法阅读的版本无法在Excel
中打开我不应该在本地保存 Excel 文件,所以我使用的是流。本地保存是我能够做到这一点的唯一方式吗?这是我第一次使用流,所以我怀疑我在那里做错了什么但我不太确定,我让 运行 陷入死胡同。任何建议将不胜感激!
想通了!在我的代码中拼错了 xlsx 扩展名(当添加到 MultipartFormDataContent 时),这导致所有内容都消失了。现在它运行完美:)