Grandma says you cannot post a Mutipart/form-data using an HttpRequest in APEX?
Well, if she says this now you can tell her this is no more true!
All comes from a CloudSpokes challenge (here is the link)...at the time of starting the challenge I was absolutely sure I would have ended up the challenge in less than a day: http gets/posts are not a big problem in APEX...well so it seemed.
To complete the challenge you had to make 4 REST calls (login, book a new upload, upload the file, set permissions): during testing the last step always failed.
This was the first time I jumped in front of this issue.
If you don't want to know what I did, go directly here.
The first thing I noted was that you cannot send a base64 encoded file to a server expecting a binary file...It wans't that obvious to me, because I've never struggled with file encoding.
The first code was something like this:
public static HTTPResponse uploadFile(Attachmnet file) { String boundary = '__boundary__xxx'; String header = '--'+boundary+'\n'; + 'Content-Disposition: form-data; name="data"; filename="'+file.name +'"\nContent-Type: application/octet-stream\n\n'; String footer = '\n--'+boundary+'--'; String body = EncodingUtil.base64Encode(file.Body); //encodes the blob into a base64 encoded String body = header + body + footer; HttpRequest req = new HttpRequest(); req.setHeader('Content-Type','multipart/form-data; boundary='+boundary); req.setMethod('POST'); req.setEndpoint('http://posttestserver.com/post.php?dir=what_a_wonderful_post'); //COOL site to test form uploads req.setBody(body); req.setTimeout(60000); req.setHeader('Content-Length',String.valueof(body.length())); Http http = new Http(); return http.send(req); }
Then I was all "Eureka! An encoded string cannot be understood if the server needs a binary", so the only thing to do is to make a concatenation of header + file.Body.toString() + footer! This works only if the Blob comes from a text file (i.e. TXT, XML or CSV files): in these cases you don't have any problem...but with binary data all you have is the error:
Blob is not a valid UTF-8 string
I had to find another way.
Searching the web for "uploading binary data using apex" I found those bad links:
- http://success.salesforce.com/ideaView?id=08730000000Kr80AAC
- http://boards.developerforce.com/t5/Apex-Code-Development/Image-upload-using-multipart-form-data/td-p/243335
- http://boards.developerforce.com/t5/Apex-Code-Development/sending-a-non-ascii-file-via-Http-POST/td-p/116662
That leaded to the block of comments you can see in the challenge's dashboard.
I didn't give up anyway. I had all data needed to send the request so I knew the solution was out there.
First thing was to understand if there was a way to merge Blobs types: it is not possible in APEX if you don't have the original data (in that case you use String concatenation or List of Integers concatenation, if you have bynary data in form of intergers list).
So I came up with the idea to merge header, body and footer using base64 encoded version, something like this:
String encoded = EncodingUtil.base64Encode(Blob.valueOf(header))+EncodingUtil.base64Encode(file.Body)+EncodingUtil.base64Encode(Blob.valueOf(footer)); req.setBodyAsBlob(EncodingUtil.base64Decode(encoded));
I found that sometimes it worked (after a bit I understood that that times I was extremely lucky!!).
Debugging and searching the web (see this post for example) I came to know that a base64 encoded String could have padding characters because the base64 encoding is done using chunks of 3 bytes (see Google for details), and if data is not multiple of 3 bytes this padding in needed.
So I decided to remove the trailing "=" from each encoded chunck of the body request and paste them together. But it's not the proper way to play with encoded base64 strings, as removing trailing padding needs a reencoding of the original data.
The idea was to remove in some way, without messing with the encoded strings, all trailing padding "=".
For the header string it was simple, because it was simple text and I could have added some blank spaces to get an encoded string without "=". That's:
String boundary = '__boundary__xxx'; String header = '--'+boundary+'\n'; + 'Content-Disposition: form-data; name="data"; filename="'+file.name +'"\nContent-Type: application/octet-stream'; String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\n\n')); //this ensures no trailing "=" padding while(headerEncoded.endsWith('=')) { header+=' '; headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\n\n')); }
So in practice I add extra spaces before the "\n\n" ending characters till I have an encoded string without padding.
The Blob file is the main problem. I need the unencoded data to get the needed trailing, so I need a String value of the body: even if with that String how can I change the file to avoid the "=" ? As this data can be anything (form txt files to encoded zips), it is not so simple to add some padding character to avoid the "=" padding (not clear I know)...
If the encoded body doesn't contain any trailing "=", now the problem is over, the sum of the encoded header, body and footer works.
The problem is the last 4 bytes of the encoded body. That is from the 0th byte to the N-4th byte of the file I have no problem, becase it is an encoded version without "=" trailing.
How do I encode those last 4 bytes merging them with the footer?
I discovered that the HttpRequest class has a strange behavior: the setBodyAsBlob() and getBody() are complementary for the use I need. That is the following code doens't throw a "Blob is not a valid UTF-8 string" exception:
Blob body = file.body; HttpRequest tmp = new HttpRequest(); tmp.setBodyAsBlob(body); String bodyString = tmp.getBody(); System.debug('## Output body:'+bodyString );
The result is a messing sequence of characters. Are they properly encoded? Yes they are, this is a kind of test:
Blob decoded4Bytes = EncodingUtil.base64Decode('AA=='); System.debug('FIRST ENCODING: '+EncodingUtil.base64Encode(decoded4Bytes)); HttpRequest tmp = new HttpRequest(); tmp.setBodyAsBlob(decoded4Bytes); System.debug('LAST ENCODING: '+EncodingUtil.base64Encode(tmp.getBodyAsBlob()));
Using different kind of random encoded data (other that "AA==") the results of encoding, blobbing, httpRequesting (??!!), is always the same.
This is what i needed:
- decode the last 4 bytes in blob
- append it into an HttpRequest using the "setBodyAsBlob()"
- get the body as string with "getBody()"
- merge this string with the footer
- base64 encode the resulting string
- merge the base64 encoding of header, file body (from 0 to N-4th byte), previous merged string
- base64 unencoding the resulting string
- here you are the Blob you needed!
public static HTTPResponse uploadFile(Attachmnet file) { String boundary = '__boundary__xxx'; String header = '--'+boundary+'\n'; body += 'Content-Disposition: form-data; name="data"; filename="'+file.name +'"\nContent-Type: application/octet-stream'; String footer = '\n--'+boundary+'--'; // no trailing padding on header by adding ' ' before the last "\n\n" characters String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\n\n')); //this ensures no trailing "=" padding while(headerEncoded.endsWith('=')) { header+=' '; headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\n\n')); } //base64 encoded body String bodyEncoded = EncodingUtil.base64Encode(file.body); //base64 encoded footer String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer)); Blob bodyBlob = null; //last encoded body bytes String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length()); //if the last 4 bytes encoded base64 ends with the padding character (= or ==) then re-encode those bytes with the footer //to ensure the padding is added only at the end of the body if(last4Bytes.endsWith('=')) { Blob decoded4Bytes = EncodingUtil.base64Decode(last4Bytes); HttpRequest tmp = new HttpRequest(); tmp.setBodyAsBlob(decoded4Bytes); String last4BytesFooter = tmp.getBody()+footer; bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded.substring(0,bodyEncoded.length()-4)+EncodingUtil.base64Encode(Blob.valueOf(last4BytesFooter))); } else { bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded); } if(bodyBlob.size()>3000000) { //this a "public class CustomException extends Exception{}" throw new CustomException('File size limit is 3 MBytes'); } HttpRequest req = new HttpRequest(); req.setHeader('Content-Type','multipart/form-data; boundary='+boundary); req.setMethod('POST'); req.setEndpoint('http://posttestserver.com/post.php?dir=watchdox'); req.setBodyAsBlob(bodyBlob); req.setTimeout(60000); req.setHeader('Content-Length',String.valueof(req.getBodyAsBlob().size())); Http http = new Http(); HTTPResponse res = http.send(req); return res; }
I tested it with different kind of files, dimensions and it always worked. I'd like to know your thoughts.
See ya!
UPDATE
See this improvement to my solution. I'll add the content right here:public static void uploadFile(Blob file_body, String file_name, String reqEndPoint){ // Repost of code with fix for file corruption issue // Orignal code postings and explanations // http://enreeco.blogspot.in/2013/01/salesforce-apex-post-mutipartform-data.html // http://salesforce.stackexchange.com/questions/24108/post-multipart-without-base64-encoding-the-body // Additional changes commented GW: that fix issue with occasional corruption of files String boundary = '----------------------------741e90d31eff'; String header = '--'+boundary+'\nContent-Disposition: form-data; name="file"; filename="'+file_name+'";\nContent-Type: application/octet-stream'; // GW: Do not prepend footer with \r\n, you'll see why in a moment // String footer = '\r\n--'+boundary+'--'; String footer = '--'+boundary+'--'; String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n')); while(headerEncoded.endsWith('=')) { header+=' '; headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n')); } String bodyEncoded = EncodingUtil.base64Encode(file_body); // GW: Do not encode footer yet // String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer)); Blob bodyBlob = null; String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length()); // GW: Replacing this entire section /* if(last4Bytes.endsWith('=')) { Blob decoded4Bytes = EncodingUtil.base64Decode(last4Bytes); HttpRequest tmp = new HttpRequest(); tmp.setBodyAsBlob(decoded4Bytes); String last4BytesFooter = tmp.getBody()+footer; bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded.substring(0,bodyEncoded.length()-4)+EncodingUtil.base64Encode(Blob.valueOf(last4BytesFooter))); } else { bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded); } */ // GW: replacement section to get rid of padding without corrupting data if(last4Bytes.endsWith('==')) { // The '==' sequence indicates that the last group contained only one 8 bit byte // 8 digit binary representation of CR is 00001101 // 8 digit binary representation of LF is 00001010 // Stitch them together and then from the right split them into 6 bit chunks // 0000110100001010 becomes 0000 110100 001010 // Note the first 4 bits 0000 are identical to the padding used to encode the // second original 6 bit chunk, this is handy it means we can hard code the response in // The decimal values of 110100 001010 are 52 10 // The base64 mapping values of 52 10 are 0 K // See http://en.wikipedia.org/wiki/Base64 for base64 mapping table // Therefore, we replace == with 0K // Note: if using \n\n instead of \r\n replace == with 'oK' last4Bytes = last4Bytes.substring(0,2) + '0K'; bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes; // We have appended the \r\n to the Blob, so leave footer as it is. String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer)); bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded); } else if(last4Bytes.endsWith('=')) { // '=' indicates that encoded data already contained two out of 3x 8 bit bytes // We replace final 8 bit byte with a CR e.g. \r // 8 digit binary representation of CR is 00001101 // Ignore the first 2 bits of 00 001101 they have already been used up as padding // for the existing data. // The Decimal value of 001101 is 13 // The base64 value of 13 is N // Therefore, we replace = with N // Note: if using \n instead of \r replace = with 'K' last4Bytes = last4Bytes.substring(0,3) + 'N'; bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes; // We have appended the CR e.g. \r, still need to prepend the line feed to the footer footer = '\n' + footer; String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer)); bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded); } else { // Prepend the CR LF to the footer footer = '\r\n' + footer; String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer)); bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded); } HttpRequest req = new HttpRequest(); req.setHeader('Content-Type','multipart/form-data; boundary='+boundary); req.setMethod('POST'); req.setEndpoint(reqEndPoint); req.setBodyAsBlob(bodyBlob); req.setTimeout(120000); Http http = new Http(); HTTPResponse res = http.send(req); }
Nice work. You did what what many thought to be impossible. Very impressive.
ReplyDeleteGreat job, yes sir! It is a breakthrough. Will have been hard work.
ReplyDeletegood work!!!
ReplyDeleteHi Guys thanks, I abused of my mind doing this :)
ReplyDeleteyou're the best!!
ReplyDeleteHi,
ReplyDeleteI am currently working on similar task. I have one small question regarding the final code that is pasted above.
body+='Content-Disposition: ....
where you have used this body variable in your code. i.e Do I need to change the line no.19 like the blow.
String bodyEncoded = body+EncodingUtil.base64Encode(file.body);
Please advice.
Thanks,
Indy.
Hi Indy, it's a typo.
ReplyDeleteLine 5 is "header += ..." and not "body += ..." (actually you can concatenate the string in line 5 with the string in line 4).
The code has been modified before posting to the blog, that's why the typo.
Hope this can help.
Enrico
Hi I am trying to use the same code for BOX.com upload and getting Bad Request error, Any thought why it not working for box.com.
ReplyDeleteYou should check the debug and try to figure out why the sending body is not in the expected format of what Box.com expectes...no more hints sorry!
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteIt work fine with DOC,PDF,PNG but not with DOCX from Mac,
DeleteI am not able to understand why encoding not working for DOCX, Any luck why its happen with these file format.
Can you help me to solve this for DOCX ?
This comment has been removed by the author.
ReplyDeleteby Using the debug log Encoding and Decoding is fine.
DeleteAfter week spend no 100% solution GOT any where. one space header+=' '; corrupting the image file with extra space in binary.
ReplyDeleteValidated in http://www.base64decode.org/. Seems need to look more work around with this code.
I am having prolem:
ReplyDeleteFailed to parse multipart/form-data content: Stream ended unexpectedly
Can anybody help me?
This solution does not work and will not work. Take any file and open in any binary viewer. Checkout the last one byte or two bytes of the file. If the last byte is non-UTF character e.g 'DF', the above solution will miserably fail. Reason being, when you do tmp.setBodyAsBlob(decoded4Bytes) and then tmp.getBody(), no doubt it doesnt raise UTF8 exception, but what it does is, it will replace any unsupported UTF character with combination of three bytes, something like EF,.GH FD, and this changes the content of your binary file.
ReplyDeleteThis comment has been removed by the author.
DeleteAnother thing, had this tmp.setBodyAsBlob(decoded4Bytes) and then tmp.getBody() trick worked, you wouldn't have required to do all these things, like taking last 4 encoded bytes, decoding and then using them. You could have simply set the entire File's data using setBodyAsBlob and retrieve it using getBody, which wont raise.
ReplyDeleteIn all I would say, good try but certainly doesn't work with every fail. This also explains above queries like why this solution didnt work for DOCX files, because DOCX files are zip file based formats and gets corrupted when their content changes. Your algorithm would be changing the last bytes to 'EF GH FD'
Are there any alternative way how to send HTTP post multipart/form-data contentType request???
ReplyDeleteCurrently there doesn't exist a way to do that. Above solution can work for a small subset of files but not all.
DeleteThis is example for java. But i use upload files throw web form with javascript. Anybody know, how send filenames to restful APEX services?
ReplyDeleteHi I am use the same code for BOX.com upload file and getting StatusCode=400 and Bad Request error and saw in debug log file format is "--1376307429601
ReplyDeleteContent-Disposition: form-data; name="fileName" ; filename="@fileName.txt ;parent_id=788878787"
Content-Type:text/plain
Test box
----1376307429601-- "
Please help where i done the mistake and some hits
Hi Onkar
ReplyDeletewere u able to upload docx file on box ?
Anyone else worked on Salesforce-box integration?
Hi @enreeco, @gagan and @onkar.
ReplyDeleteI was also having the same requirement and used the above code. However as mentioned in few comments above the code works sometimes and not all the times. Th reason is that when we convert the last 4 bytes of encoded part to string using the HttpRequest class, it corrupts the data. The data length of the returned data is not the same and so the complete image data gets corrupted which is though successfully accepted as a valid request by Salesforce but rejected while processing the same.
Did you get any luck for any developments on this after that?
Kamal
Hi Enrico Murru,
ReplyDeletei am facing some problem while sending the multipart/form-data request through apex. i have gone through this blog but i cannot figure out why my code is failing. i want to send two file in the request but somehow second parameter i.e. second file is not getting sent.
https://salesforce.stackexchange.com/questions/251125/multipart-form-data-no-mapping-found-for-http-request-for-uri
can you please help me out in this?
This comment has been removed by the author.
ReplyDeleteI use this code to send a file from Salesforce to M-files, it worked well as long as the file size is less than 12000000, I know that this is a Salesforce Limit, do you know if there is any workaround.
ReplyDeleteThanks
Hi gosfa, refer tp https://blog.enree.co/2013/01/salesforce-apex-post-mutipartform-data.html, the new blog's house :)
DeleteUnfortunately there is no way to workaround this limit
Hi I have similar challenge , I am sending file from salesforce to external server where text format seems fine , other than text all type files are corrupted.
ReplyDeleteCan SomeOne Please help me with the code. how to upload a file from local to the field of the salesforce custom object."In Lightning".
ReplyDeleteYou can refer this
Deletehttp://sfdcmonkey.com/2017/09/25/file-upload-lightning-component/
This comment has been removed by the author.
ReplyDeleteHi,
ReplyDeleteI am trying to upload a text file (also tried PDF, etc) to Salesforce.
Text file contains 'hello world'.
I am opening it in binary mode:
with open(filen, "rb") as f:
bodyEncoded = base64.b64encode(f.read())
Then after all the code you have I am composing multi-part message for SalesForce:
------------------------------741e90d31eff
Content-Disposition: form-data; name="entity_content";
Content-Type: application/json;
{"ContentDocumentId": "0699E000000lKbLQAU", "ReasonForChange": "Large file upload", "PathOnClient": "hello_world.txt"}
------------------------------741e90d31eff
Content-Disposition: form-data; name="VersionData"; filename="hello_world.txt";
Content-Type: application/octet-stream
b'aGVsbG8gd29ybGQK'
------------------------------741e90d31eff--
After uploading it, when I open uploaded file I just see its content as:
b'aGVsbG8gd29ybGQK'
I have tried also a pdf, but again, original file and uploaded-downloaded file md5 checksums are different.
Could you help to understand what I might be doing wrong?
Hi I am using the same to send file to upload as transient document in adobe echosign. But I am getting bad request error.
ReplyDeleteHi. Your code seems to work but Im getting the following error in my backend
ReplyDeletejava.lang.IllegalArgumentException: Invalid content disposition format
at org.springframework.http.ContentDisposition.parse(ContentDisposition.java:327) ~[spring-web-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
My backend works fine if I use Postman to upload the file it works. But when I use your class it does not. Could you help to identify what is the problem?
Hello Allan , In postman , under headers . what is the key value pair used for body to do file uploads . Please suggest what other key value paid needs to be used apart from ftp host , username , password , port , content type-multipart/form-data , ftp-tye-FTP . Thanks in advance
DeleteHello I used your code to send a PDF via callout to a company that parses out the fields. It sends the PDF but sometimes it turns it green and most of the file is all messed up. The lines are everywhere and most of it is unreadable. Some of it is. Can anyone please help me fix this??? No idea why it's going it.
ReplyDeleteHello, the code for http requests works for me but it fails for https could you help me?
ReplyDeleteHello, Can you please help me how can i add multiple parameters in body?
ReplyDeletedid you find a solution? I have the same problem.
DeleteHey guys, I used this code in my previous project and sometimes files used to corrupt. To fix that I had to go for the alternate way , I integrated salesforce with Java(STS) and exposed files to java and thru Java files were uploading to third party app. which worked fine. however I don't suggest this option too because it has other drawback too.
ReplyDeleteUsing this code yields a "Unsupported Media Type 415" error for me, any idea what that might be? Base64 encoded PDF file...
ReplyDeleteIm also geeting Unsupported Media Type 415" error.Can anynoe assist?
ReplyDeleteThank you for the post, so so super helpful!!!
ReplyDeleteam I the only one with an error when the file is over 12mb?
ReplyDeleteit happens on:
String bodyEncoded = EncodingUtil.base64Encode(file_body);
Necesito implementar el codigo para subir uno o mas archivos. Como Haria para implementarlo para varios archivos
ReplyDeletei am painfully trying to add a second form-data field to the request body and keep failing. eventually the api i'm communicating with quit with the error of not receiving that second form-data field and started giving me internal server errors... pleasee help anyone? i'm trying to do this: https://developer.ilovepdf.com/docs/api-reference#upload
ReplyDeleteplease look at Example HTTP Request! What can I do?!
Good job. Really helpful.
ReplyDeleteWow... It's an amazing job. I've wasted my time trying to upload files to Dropbox until I found this article. Thank you very much.
ReplyDeleteFinally, I could upload pdf and txt file... The image files (png, jpg) can not be open once it's uploaded in Dropbox. If you have any update on this I appreciate it.
Thanks,
Pedro
Hi, i am trying above code but getting 500 Internal server error
ReplyDeleteanybody know why i am getting this
Hi, do you get to know why you were getting 500 error for the above code ?
Deletepublic static void uploadFile2(Blob file_body, String file_name ){
ReplyDeleteRg_FileUploadService obj = new Rg_FileUploadService();
string accessToken = obj.genAccessToken();
String boundary = '----------------------------741e90d31eff';
String header = '--'+boundary+'\nContent-Disposition: form-data; name="file"; filename="'+file_name+'";\nContent-Type: application/octet-stream';
String footer = '--'+boundary+'--';
String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
while(headerEncoded.endsWith('='))
{
header+=' ';
headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
}
String bodyEncoded = EncodingUtil.base64Encode(file_body);
Blob bodyBlob = null;
String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length());
if(last4Bytes.endsWith('==')) {
last4Bytes = last4Bytes.substring(0,2) + '0K';
bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;
String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
} else if(last4Bytes.endsWith('=')) {
last4Bytes = last4Bytes.substring(0,3) + 'N';
bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;
footer = '\n' + footer;
String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
} else {
footer = '\r\n' + footer;
String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
}
HttpRequest req = new HttpRequest();
req.setHeader('Content-Type','multipart/form-data; boundary='+boundary);
req.setMethod('POST');
req.setHeader('Authorization','Bearer ' + accessToken);
req.setEndpoint('https://saas.docufree.com/dfwebservice/v3/files/capture/folder?targetId=3486');
req.setBodyAsBlob(bodyBlob);
req.setTimeout(120000);
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug('RESP '+res);
System.debug('RESP BDY '+res.getBody());
}
this is returning 500 response
Hi,
DeleteDid you get answer to this, why you're getting 500 response ?
I'm also getting the same response.
I am beginner.I do not know how to run this uploadFile2() .Anyone plz help me
ReplyDeleteThis article is brimming with information about the salesforce service cloud for more like this. I have additionally discovered an article anybody can check Salesforce Service Cloud , for more data, it was knowingly more instructive. You may discover more insights regarding it here.
ReplyDeleteNeed help , I have to pass other parameter to form the Request the "Form-data", example status, priority and File(attachment as well, but keep on getting error. Please help me- salesforceguru81@gmail.com
ReplyDeletethank you in advance
ReplyDeleteThank you so much for sharing this incredible article with a really nice explanation of all of the details. I wasn't aware of how much Salesforce breaks the String while sending the request with multipart/form-data contents.
ReplyDeleteBest regards from Brazil!
This comment has been removed by the author.
ReplyDeleteHello Enrico, first of all, thank you very much for this contribution. I don't think I would have been able to solve this functionality if I hadn't come across your blog.
ReplyDeleteSecondly, in my particular case, I copied the updated solution from the 'UPDATE' section, but it didn't work. When I compared it to other solutions, I noticed that the line that builds the header:
String header = '--'+boundary+'\nContent-Disposition: form-data; name="file"; filename="'+file_name+'";\nContent-Type: application/octet-stream';
Was using \n to insert a line break. When I replaced it with \r\n, I got it to work. Something related to this is already mentioned in your previous solutions, but maybe it was missed in the more complete solution?
Oh, and I also replaced Content-Type: application/octet-stream with Content-Type: image/png because I only need to send images.
Wow Enrico! A lot of work there. I am in the same boat. I am wondering if anything in SF has changed. They allow multipart to their own API's with binary data. Check this: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_insert_update_blob.htm
ReplyDeleteHave you tried this approach?