Trouble uploading a document to Salesforce using c#

Viewed 125

I'm referencing the url https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_insert_update_blob.htm#inserting_a_contentversion and I see the curl methods, but c# can't use c#. So I've attempted creating the multiPartForm request with no avail.

Below are the two specific curl calls I'm attempting to recreate in C#.

--boundary_string
Content-Disposition: form-data; name="entity_content";
Content-Type: application/json

{
    "ContentDocumentId" : "069D00000000so2",
    "ReasonForChange" : "Marketing materials updated",
    "PathOnClient" : "Q1 Sales Brochure.pdf"
}

--boundary_string
Content-Type: application/octet-stream
Content-Disposition: form-data; name="VersionData"; filename="Q1 Sales Brochure.pdf"

Binary data goes here.

--boundary_string--

and

--boundary_string
Content-Disposition: form-data; name="entity_document";
Content-Type: application/json

{  
    "Description" : "Marketing brochure for Q1 2011",
    "Keywords" : "marketing,sales,update",
    "FolderId" : "005D0000001GiU7",
    "Name" : "Marketing Brochure Q1",
    "Type" : "pdf"
}

--boundary_string
Content-Type: application/pdf
Content-Disposition: form-data; name="Body"; filename="2011Q1MktgBrochure.pdf"

Binary data goes here.

--boundary_string--

Here are my code attempts, with the byte[] and in some case a base64 string. I've switched out the base[] and the base64 string in each case and I have had no luck, the json string is correctly formatted, the token is valid, just keep getting back a 400 error. (bad request) from salesforce.

public async Task<HttpResponseMessage> PostBlobAsync(string url, string token, string json, byte[] pdfBase64)
{
    try
    {
        using (var httpContent = new MultipartFormDataContent("boundary_string"))
        {
            httpContent.Headers.ContentType.MediaType = "multipart/form-data";

            httpContent.Add(new StringContent(json, System.Text.Encoding.UTF8, "application/json"));

            //var content = new StringContent(pdfBase64.ToString(), System.Text.Encoding.UTF8, "application/octet-stream");
            var content = new ByteArrayContent(pdfBase64, 0, pdfBase64.Length - 1);
            content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");

            _logger.LogInformation("HTTP Client PostAsync calling URL:{0} at {1}", url, DateTime.UtcNow);
            _httpClient.UseBearerToken(token);
            var response = await _httpClient.PostAsync(url, httpContent);

            if (!response.IsSuccessStatusCode)
            {
                var ex = CreateException(response);
                throw ex;
            }

            return response;
        }
    }
    catch (Exception ex)
    {
        _logger.LogInformation(ex.Message, url, DateTime.UtcNow);
        throw ex;
    }
}

public async Task<HttpResponseMessage> PostBlobAsync2(string url, string token, string json, string fileBytes)
{
    try
    {
        using (var httpContent = new MultipartFormDataContent("boundary_string"))
        {
            httpContent.Headers.ContentType.MediaType = "multipart/form-data";

            var content1 = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
            var contentDisposition1 = new ContentDispositionHeaderValue("form-data");
            contentDisposition1.Name = "entity_content";
            content1.Headers.ContentDisposition = contentDisposition1;
            httpContent.Add(content1);

            //var content2 = new StringContent(pdfBase64.ToString(), System.Text.Encoding.UTF8, "application/octet-stream");
            //var content2 = new StringContent(fileBytes, System.Text.Encoding.UTF8, "application/pdf");
            var content2 = new StringContent(fileBytes);
            content2.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
            var contentDisposition2 = new ContentDispositionHeaderValue("form-data");
            contentDisposition2.Name = "VersionData";
            contentDisposition2.FileName = "Change Request.pdf";
            httpContent.Add(content2);

            _logger.LogInformation("HTTP Client PostAsync calling URL:{0} at {1}", url, DateTime.UtcNow);
            _httpClient.UseBearerToken(token);
            var response = await _httpClient.PostAsync(url, httpContent);

            if (!response.IsSuccessStatusCode)
            {
                var ex = CreateException(response);
                throw ex;
            }

            return response;
        }
    }
    catch (Exception ex)
    {
        _logger.LogInformation(ex.Message, url, DateTime.UtcNow);
        throw ex;
    }
}

public async Task<HttpResponseMessage> PostBlobAsync3(string url, string token, string caseId, string fileBytes)
{
    try
    {
        using (var httpContent = new MultipartFormDataContent("boundary_string"))
        {
            //httpContent.Headers.ContentType.MediaType = "multipart/form-data";

            var dictionary = new Dictionary<string, string>();
            dictionary.Add("Description", "New Change Request");
            dictionary.Add("Keywords", "Change,Request");
            dictionary.Add("FolderId", caseId);
            dictionary.Add("Type", "pdf");

            var json = JsonConvert.SerializeObject(dictionary);

            var content1 = new StringContent(json);
            content1.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
            var contentDisposition1 = new ContentDispositionHeaderValue("form-data");
            contentDisposition1.Name = "entity_document";
            content1.Headers.ContentDisposition = contentDisposition1;
            httpContent.Add(content1);

            //var content2 = new StringContent(pdfBase64.ToString(), System.Text.Encoding.UTF8, "application/octet-stream");
            //var content2 = new StringContent(fileBytes, System.Text.Encoding.UTF8, "application/pdf");
            var content2 = new StringContent(fileBytes);
            content2.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf");
            var contentDisposition2 = new ContentDispositionHeaderValue("form-data");
            contentDisposition2.Name = "Body";
            contentDisposition2.FileName = "Change Request.pdf";
            httpContent.Add(content2);

            _logger.LogInformation("HTTP Client PostAsync calling URL:{0} at {1}", url, DateTime.UtcNow);
            _httpClient.UseBearerToken(token);
            var response = await _httpClient.PostAsync(url, httpContent);

            if (!response.IsSuccessStatusCode)
            {
                var ex = CreateException(response);
                throw ex;
            }

            return response;
        }
    }
    catch (Exception ex)
    {
        _logger.LogInformation(ex.Message, url, DateTime.UtcNow);
        throw ex;
    }
}

public async Task<bool> PostBlobAsync4(string url, string token, string caseId, byte[] fileBytes)
{
    string boundary = "boundary_string";
    var req = System.Net.WebRequest.Create(url);

    req.Headers.Add("Authorization: OAuth " + token);
    req.ContentType = "multipart/form-data; boundary=" + boundary;
    req.Method = "POST";
    var os = req.GetRequestStream();

    string body = "";
    body += $"\r\n--{boundary}\r\n";
    body += "Content-Disposition: form-data; name='entity_document'\r\n";
    body += "Content-Type: application/json\r\n\r\n";

    var dictionary = new Dictionary<string, string>();
    dictionary.Add("Description", "New Change Request");
    dictionary.Add("Keywords", "Change,Request");
    dictionary.Add("FolderId", caseId);
    dictionary.Add("Type", "pdf");
    dictionary.Add("Name", "Change Request");

    var json = JsonConvert.SerializeObject(dictionary);
    body += json;

    // Add header for binary part 
    body += "\r\n--" + boundary + "\r\n";
    body += "Content-Disposition: form-data; name='Body'; filename='1.txt'\r\n";
    body += "Content-Type: binary/octet-stream\r\n\r\n";

    byte[] data = System.Text.Encoding.ASCII.GetBytes(body);
    os.Write(data, 0, data.Length);

    os.Write(fileBytes, 0, fileBytes.Length);

    byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
    os.Write(trailer, 0, trailer.Length);

    os.Close();

    WebResponse resp;

    try
    {
        resp = await req.GetResponseAsync();
    }
    catch(WebException ex)
    {
        return false;
    }

    return true;
}
0 Answers
Related