0

I am integrating with one of the provider who accepts a file to upload in their system. While doing so they require the file to be sent as multipart/form-data in the following format !!

I tried configuring it as MultiPart form data using Base64 String still it is not working !!

-H "accept: application/json"
-H "x-api-key: API_KEY" 
-H "x-api-token: API_TOKEN" 
-H "Content-Type: multipart/form-data" 
-F "file=@b4b35527-522d-4228-a266-bdaa80e28a8b.jpg;type=image/jpeg"
Helen
  • 87,344
  • 17
  • 243
  • 314
Somya Tiwari
  • 145
  • 3
  • 8
  • It looks as follows while doing from POSTMAN curl --location --request POST URL \ --header 'x-api-token: API_TOKEN' \ --header 'x-api-key: API_KEY' \ --header 'accept: application/json' \ --form 'file=@/C:/Users/somya/OneDrive/Documents/CL 1.png' – Somya Tiwari Jul 25 '20 at 04:11
  • 1
    Did you try this http://www.fishofprey.com/2017/04/steps-required-to-support-posting.html ? – Nguyễn Thắng Jul 27 '20 at 07:23

2 Answers2

0

what you are looking for is not supported by the salesforce apex callout. it's still in the salesforce Idea Exchange here is the link for the same.

https://trailblazer.salesforce.com/ideaView?id=08730000000Kr80AAC

You can vote for it but currently, multipart/form-data header is not supported.

please let me know if you have any questions.

0

Salesforce does support multipart/form-data but what it doesn't support is sending a Image as Blob.

For my requirement I needed to send the image / PDF / attachment as a form data. I used a slightly modified version of http://www.fishofprey.com/2017/04/steps-required-to-support-posting.html

I got another blob method to include the Images & Attachments as blob. Currently i have not added the codec for videos & other documents, but soon i will be adding those as the API does support that one.

Find here with teh modified version of HttpFormBuilder to include Images & Other Attachments as blob. We just need to add appropriate Codec.

public class HttpFormBuilder_Custom {
    private final static string Boundary = '1ff13444ed8140c7a32fc4e6451aa76d';
    public static string GetContentType() {
        return 'multipart/form-data; charset="UTF-8"; boundary="' + Boundary + '"';
    }
    private static string SafelyPad(
        string value,
        string valueCrLf64,
        string lineBreaks) {
        string valueCrLf = '';
        blob valueCrLfBlob = null;

        while (valueCrLf64.endsWith('=')) {
            value += ' ';
            valueCrLf = value + lineBreaks;
            valueCrLfBlob = blob.valueOf(valueCrLf);
            valueCrLf64 = EncodingUtil.base64Encode(valueCrLfBlob);
        }
        return valueCrLf64;
    }
    public static string WriteBoundary() {
        string value = '--' + Boundary + '\r\n';
        blob valueBlob = blob.valueOf(value);

        return EncodingUtil.base64Encode(valueBlob);
    }
    public static string WriteBoundary(
        EndingType ending) {
        string value = '';

        if (ending == EndingType.Cr) {
            value += '\n';
        } else if (ending == EndingType.None) {
            value += '\r\n';
        }
        value += '--' + Boundary + '--';

        blob valueBlob = blob.valueOf(value);

        return EncodingUtil.base64Encode(valueBlob);
    }

    /**
     *  Write a key-value pair to the form's body.
     */
    public static string WriteBodyParameter(string key, string value) {
        string contentDisposition = 'Content-Disposition: form-data; name="' + key + '"';
        string contentDispositionCrLf = contentDisposition + '\r\n\r\n';
        blob contentDispositionCrLfBlob = blob.valueOf(contentDispositionCrLf);
        string contentDispositionCrLf64 = EncodingUtil.base64Encode(contentDispositionCrLfBlob);
        string content = SafelyPad(contentDisposition, contentDispositionCrLf64, '\r\n\r\n');
        string valueCrLf = value + '\r\n';
        blob valueCrLfBlob = blob.valueOf(valueCrLf);
        string valueCrLf64 = EncodingUtil.base64Encode(valueCrLfBlob);

        content += SafelyPad(value, valueCrLf64, '\r\n');

        return content;
    }

    /**
     *  Helper enum indicating how a file's base64 padding was replaced.
     */
    public enum EndingType {
        Cr,
        CrLf,
        None
    }
    public static string WriteBlobBodyParameter(string key, string file64, string fileName) {
        
        String mimeType = resolveMimeType(fileName);
        
        string contentDisposition = 'Content-Disposition: form-data; name="' + key + '"; filename="'+fileName+'"';
        string contentDispositionCrLf = contentDisposition + '\r\n';
        blob contentDispositionCrLfBlob = blob.valueOf(contentDispositionCrLf);
        string contentDispositionCrLf64 = EncodingUtil.base64Encode(contentDispositionCrLfBlob);
        string content = SafelyPad(contentDisposition, contentDispositionCrLf64, '\r\n');
        
        string contentTypeHeader = 'Content-Type: ' + mimeType;
        string contentTypeCrLf = contentTypeHeader + '\r\n\r\n';
        blob contentTypeCrLfBlob = blob.valueOf(contentTypeCrLf);
        string contentTypeCrLf64 = EncodingUtil.base64Encode(contentTypeCrLfBlob);
        content += SafelyPad(contentTypeHeader, contentTypeCrLf64, '\r\n\r\n');
        
        integer file64Length = file64.length();
        String last4Bytes = file64.substring(file64.length()-4,file64.length());

        // Avoid padding the file data with spaces, which SafelyPad does
        // http://salesforce.stackexchange.com/a/33326/102
        EndingType ending = EndingType.None;
        if (last4Bytes.endsWith('==')) {
            last4Bytes = last4Bytes.substring(0,2) + '0K';
            file64 = file64.substring(0,file64.length()-4) + last4Bytes;
            ending = EndingType.CrLf;
        } else if (last4Bytes.endsWith('=')) {
            last4Bytes = last4Bytes.substring(0,3) + 'N';
            file64 = file64.substring(0,file64.length()-4) + last4Bytes;
            ending = EndingType.Cr;
        }
               
        content += file64;
        
        content += WriteBoundary(ending);
        return content;
    }
    
    private static String resolveMimeType(String fileName) {
        String fileType = fileName.substringAfterLast('.');
        String mimeType = 'image/png'; // fallback value
        if (fileType.equalsIgnoreCase('png')) {
            mimeType = 'image/png';
        } else if (fileType.equalsIgnoreCase('jpeg') || fileType.equalsIgnoreCase('jpg')) {
            mimeType = 'image/jpg';
        } else if (fileType.equalsIgnoreCase('pgm')) {
            mimeType = 'image/x-portable-graymap';
        } else if (fileType.equalsIgnoreCase('ppm')) {
            mimeType = 'image/x-portable-pixmap';            
        }
        return mimeType;
    }
}
Somya Tiwari
  • 145
  • 3
  • 8