Reputation: 1
I'm using logic apps to call the Custom Web API to upload PDFs that are stored on blob storage. I can call the endpoint directly via postman and everything works fine - i.e. upload a PDF file via postman, file gets saved correctly and I can open the file ok.
When I try to replicate the request in Logic Apps, it looks like everything is working fine - meaning blob storage PDF files gets uploaded fine and saved correctly via webapi but they are corrupted somehow - ADOBE reader error message. When I compared the original PDF file - open in notepad and WebAPI saved/uploaded PDF file (open in notepad), I do find some different symbols in PDF which makes the uploaded file corrupted (see ???? texts in body).
Any thoughts on what is causing this issue and how to resolve it?
{
"$content-type": "multipart/form-data",
"$multipart": [
{
"body": "%PDF-1.5\n%����\n1 0 obj\n<</Type/Font/Subtype/Type1/BaseFont/Times-Roman/Encoding/WinAnsiEncoding>>\nendobj\n2 0 obj\n<</Type/Font/Subtype/Type1/BaseFont/Times-Bold/Encoding/WinAnsiEncoding>>\nendobj\n3 0 obj\n<</Type/Page/Contents 4 0 R/Resources<</Font<</F3 5 0 R/F2 2 0 R/F1 1 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Parent 6 0 R/MediaBox[0 0 612 792]>>\nendobj\n5 0 obj\n<</Type/Font/Subtype/Type1/BaseFont/Helvetica/Encoding/WinAnsiEncoding>>\nendobj\n4 0 obj\n<</Length 736/Filter/FlateDecode>>stream\nx���]O�0\u0014���+�%H���\u001d�J\u001b\n\u001ak��۸@BYkP�&)I�Ŀ�S>\u0006R�tZo�X����>>�<Dg& b\nf�\u001ep�78g@��]tD�ͯ���D_���\u001b�t��P�G\u0018I��wD0C\u0002\u0014��q("�\u0015�o��h�>w���g��\u0014\u0003\u0019K�\u0014���J��n�7��e�lk�:}Vq�IxG T!҇Hg��\u0017��<Iaa��t\u0002�f�,\u0016'p9\u001d�\u0007�X�@�ܳm���i<�8�H�\u001e��QL��1P)?\t��~�\u0012�j��!\u001d�H��غ}�q�Pn�{2�\u001c%�SIb�,�\u0011�\u0016�&�\u0014����\t�kP�+�\u001f���\u0013\u0012i�]T��,��?F�\u0019b^��I��\u0004I\bR�G\u001b�����nPO|A�8+s��Imm��!��#\^w7ݣ�6YٓBaİ�un�m�:1�v\u0013\u0014#�%�&PҴy��U�#'\b9�\u0017�\u0011%��K\u0010q�/\ L@P��Kɠ���n���k\r\u0011H�\u000f�=\u0005#\u001d\u001b�ݏi\n��'Qz��y�ΗOaI4>@�h\u000eXKʅ�dl|�8�H�\u001eM�ic�����_�]YUq��\u001fy��qVd��G� <v\u0015#p;[\u000b��l�e����$�\u0007z@1��\u0019Bw-��ƪuPLؙW)A\u000e\u001981~)ԕug�\u0001ZR�����\u0017&I?��\u0017�O�%\u001c~���\u0011v�H�h���ر��â1��\u0001��l��y\r.��\u0010��\u0006Gݼ�P�vg\u0017�Դ\b������\u0018ĽWƱW�rA���\u0004bo��:Z�ʛ�+(�A�닙�����/)w\fB��2R۸���yU\u000e\u0016�~t�\u0006�-��]{b�\u0015#�1�ަ����\u0013L�\u0003�;��>���~\u0012�1"�G:_T�\u0000域�\nendstream\nendobj\n6 0 obj\n<</Type/Pages/Count 3/Kids[3 0 R 7 0 R 8 0 R]/ITXT(4.1.6)>>\nendobj\n7 0 obj\n<</Type/Page/Contents 9 0 R/Resources<</Font<</F3 5 0 R/F2 2 0 R/F1 1 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Parent 6 0 R/MediaBox[0 0 612 792]>>\nendobj\n9 0 obj\n<</Length 494/Filter/FlateDecode>>stream\nx���Oo�@\u0010���\u0014s�Hհ;��Bh�*\u0010pn�"���\u0015��v���5�\u0004*��IN�˾��μ�c�)�\u0018hK���\u0017�|\f�b�n�G4����q{�D��q\u000e�\u0006\u0007�@\u0012���p\u0012\u000e�5\u0012���\G\u0003ΆfH�X�X7�\u0013��\u0012��#��:\u001b\u0001u\u0003H\n$�B��-���s��i�����7\�Y�u7(�\u0017�Ɂ�9tΙTu^��+f1����l>�,\u001e��bv3}��\u001e�\u0002e�A\u001f�����J�Ә@\u0015���m���n��ZTq\u0000���t\u0003�uVT�aqB+\u0003�c��;\u0001=\u001e\u000e-�/��k�SԶ^\u0019���\"�Z���z\u0013-�\u001d�tTKd�������z�\r��\u00170N�y��i�e��Wq+P\u0004�\u0001\u0017Sl�P�Q�|\u000e&���\n\u0010d�d�!<S�y@����Rs�����I�1�fg�UU��²N��Y�{�\nkH˚\u0016=[�4�9���q\u0017|\u001d����=rA�B�'y�\u001f�\u0019��g>�)oΧt\u001e��d\b�s\b�Py��ߔ�~d(����2�\u001d�jDƃ0�\n\u001b@x#n]�t�~�F��&�\u001f�O8���\u0019�\u000b\n�q\nendstream\nendobj\n8 0 obj\n<</Type/Page/Contents 10 0 R/Resources<</Font<</F3 5 0 R/F2 2 0 R/F1 1 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Parent 6 0 R/MediaBox[0 0 612 792]>>\nendobj\n10 0 obj\n<</Length 798/Filter/FlateDecode>>stream\nx���[s�@\u0018���\u0015{�̘�κ\u0007��w&\u001a�i�XC��P�X2\b\u0006ȡ��\u000b�I��-�\\�\u000b�����A\u001f���\"��\u0019\nbuB�C��#�\u001a�\u001e?\u000f���q
��o��n����\t�z(X�\bE��\u0011�\-�V����g��\rcY\u0003�ą\u0010�y0b\u0016.�\u0000��\u0000fs��ȵ���\u0010\u0018��{¸��UXI4|��\n\u0005E��\u001a��]�\�h;\u0018;\f\u001b����/׳�x~{\u0013̯���+\na\u001d��\u000f�r�An^\u001cFP�b�\u0019\u0018#կ~��$���չ�7���6�.�2ɲ$[�Y�D\u001a\u0012�}�8�\u0007�b\u0003��\u0004SS�����0[�\u0010�\u0012�\u001a\u0010Ӽ������|�z\u0013Q���\u0005�w���g7���Ժ�\u001f\u0004�ݮ���,^�F����w<Y��Q�%R�[h��\u001bV��\u0003�\u000f�f|q±���
m�!X����,\�}\rîm30��!\V0�\u001b�U^�)�\u001aM\u0016�rq\u000e�F��\u000e�1'��\u0019\u0018\u0017\u00043�a�\u0006i��枦g\u001e���2�k[�\u0018�ðozE�:��z�^��HƏQ��Ju3ݦTܯ���+��\u0004�/zQ�$\u000b�H�r-��.�\f���Պw�9 m�\u001c[�@m�\u0001Y\u001d�9�њ\u0003B���̡\u001c;�\u0004s���\u0017FE^�(Lլ���0k\t߯��\u000f�\u0007����&\u0003�ۃ5���n����\u0003CL��� |A��ERƉ�'�P)+�� \u0007�E�<L���\b�3q\u0006~�˱\u000b8x�1 m�\u0018�ƀ��Ɯ�h�\u0001!Fc���Y�i���6�\b�#G�S��*
~�5��]��TS��,A��C\t��4n\u001fD�B�\u000f�\u000e�\u001d�\u001d���I�V;\u0010b�\u000eL���e�$�b[�\u0012�\u0018s0�n�;�\u0007�Wa,\rK\u001b�X;�\u001d-\f\u0004��\u0017\u001f�\u0005Bu��\u0014Dk\u000b�0�\u0002�]i\u00163�F�`G�)��\b����:�����\u000bE��~\nendstream\nendobj\n11 0 obj\n[3 0 R/XYZ 0 804 0]\nendobj\n12 0 obj\n[7 0 R/XYZ 0 804 0]\nendobj\n13 0 obj\n[8 0 R/XYZ 0 804 0]\nendobj\n14 0 obj\n<</Names[(1) 11 0 R(2) 12 0 R(3) 13 0 R]>>\nendobj\n15 0 obj\n<</Dests 14 0 R>>\nendobj\n16 0 obj\n<</Type/Catalog/Pages 6 0 R/Names 15 0 R>>\nendobj\n17 0 obj\n<</Title(Estimate Audit)/Creator(Xactimate 28.300.20080.36805)/Producer(iTextSharp 4.1.6 by 1T3XT)/CreationDate(D:20201008144100+00'00')/ModDate(D:20201008084230-06'00')>>\nendobj\nxref\n0 18\n0000000000 65535 f \n0000000015 00000 n \n0000000105 00000 n \n0000000194 00000 n \n0000000452 00000 n \n0000000364 00000 n \n0000001255 00000 n \n0000001330 00000 n \n0000002061 00000 n \n0000001500 00000 n \n0000002232 00000 n \n0000003098 00000 n \n0000003134 00000 n \n0000003170 00000 n \n0000003206 00000 n \n0000003265 00000 n \n0000003299 00000 n \n0000003358 00000 n \ntrailer\n<</Size 18/Info 17 0 R/ID [<7b2a85db783c2dfe11911d8bdba318eb><4e585c7bf06c8a42fc07c328cf0f0f89>]/Root 16 0 R>>\nstartxref\n3546\n%%EOF\n",
"headers": {
"Content-Disposition": "form-data; name="file"; filename="/imagerightextract/Xactimate-Export-File-1.zip/ESTIMATE_AUDIT_REPORT.PDF""
}
}
]
}
Additional Details below in the images.
Upvotes: 0
Views: 1829
Reputation: 668
We solved it this way and it works flawlessly. I suppose, you should replace the file body with just body('Get_file_content_2')
, however we found this to work the best.
{
"$content-type": "multipart/form-data",
"$multipart": [
{
"headers": {
"Content-Disposition": "form-data; name=\"Task\"",
"Content-Type": "application/json"
},
"body": {
"name": "test"
}
},
{
"headers": {
"Content-Disposition": "form-data; name=\"Data\"; filename=\"test.pdf\"",
"Content-Type": "application/pdf"
},
"body": {
"$content-type": "application/pdf",
"$content": "@{body('Get_file_content_2')?['$content']}"
}
}
]
}
Upvotes: 0
Reputation: 23
I had the same issue, essentially, and was able to get it to work.
I configured my Logic App as recommended in the following article:
Call service endpoints over HTTP or HTTPS from Azure Logic Apps
Which is really just using json to construct the entire body. I then used base64ToBinary on the contentBytes of the attachments because I noticed in my investigation that the following code produced a readable file:
// Reads a text file with the base64 string I pulled from an Azure Logic App "inputs"
string requestBody = ReturnContent();
byte[] encodedBytes = Convert.FromBase64String(requestBody);
File.WriteAllBytes("C:\\<your_path>\\test.pdf", encodedBytes);
Once I did this the Logic App produced a readable file.
My HTTP Action:
Just note that where you see "Attachments Name" that in the code I'm using base64ToBinary.
"body": "@base64ToBinary(items('For_each')?['contentBytes'])"
I think it's somewhat important to note that the Content-Type in the multipart section has been omitted. If you look at the actual request, it goes over as application/octet-stream, which you're not going to want to overwrite... You also don't have to specify the Content-Type of the overall request... Logic Apps figures this out as well.
The only other thing that I had to overcome was the possibility of filenames that had spaces and other normally url-encoded characters... so, I'd suggest that you specify the file name in the body as follows:
"headers": {
"Content-Disposition": "form-data;name=fileData; filename=@{encodeURIComponent(items('For_each')?['name'])}"
}
Also of note is that my Controller method (Asp.Net Core) has an IFormFile parameter... its signature looks like this:
[HttpPost("{cid}")]
[ProducesResponseType(typeof(bool), (int)HttpStatusCode.OK)]
public async Task<IActionResult> ProcessAttachment(string cid, IFormFile fileData)
I hope this helps someone else.
Upvotes: 0
Reputation: 59
I've been struggling with this one an don't have a definitive but what you can try is to use base64 where you convert your file content to base64. I have had the most success by inserting this directly in the code.
Upvotes: 1