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;
}