You need to sign in to do that
Don't have an account?
c# Issue with downloading attachments
Hi,
I am trying to download attachments from Salesforce to upload it to Sharepoint. The issue I am facing is that, the download works fine with attachments like .txt file etc, but for Word or Excel documents gives an error when trying to open the document "the document cannot be opened because there are problems with the contents".
I am doing this via c# REST api.
//example of word doc retrieval
string bodyData = HttpGet(token.instance_url + "/services/data/v28.0/sobjects/Attachment/00Pi0000001UMXa/Body", "");
byte[] encData_byte = System.Text.Encoding.UTF8.GetBytes(bodyData);
File.WriteAllBytes(@"c:\yourfile.docx", encData_byte);
From SF documents I understood that the string returned by querying the attachment is Base64Encoded. So in the code you need to ConvertFromBase64. But when I tried to convert the string using Convert.ToBase64String, it always gave an error saying "System.FormatException : Invalid character"
Have anyone faced something similar?
Cheers,
Ashwin
For the REST API the attachment body when accessed like this is returned as a regular byte stream, no base64 encoding (which is only required in soap and other XML wrapper formats). The problem is that you are converting from a byte stream to a string and back again, for something that is a byte stream, and not an encoded string, this will corrupt the data. Your HttpGet method needs to returna byte [] and not a string, and then you can write that directly to a file. (or even better HttpGet can return a stream and you can chunk copy the stream to the file without trying to have the entire document in memory)
All Answers
For the REST API the attachment body when accessed like this is returned as a regular byte stream, no base64 encoding (which is only required in soap and other XML wrapper formats). The problem is that you are converting from a byte stream to a string and back again, for something that is a byte stream, and not an encoded string, this will corrupt the data. Your HttpGet method needs to returna byte [] and not a string, and then you can write that directly to a file. (or even better HttpGet can return a stream and you can chunk copy the stream to the file without trying to have the entire document in memory)
Thanks a ton for your answer. I will check this out :)
Cheers,
Ashwin
Which library has this HttpGet method?
var auth = new AuthenticationClient();
var url = "https://test.salesforce.com/services/oauth2/token";
await auth.UsernamePasswordAsync(CustomerKey, CustomerSecret, Username, Password, url);
var client = new ForceClient(auth.InstanceUrl, auth.AccessToken, auth.ApiVersion);
const string fName = "leaseattachment";
const string qry = "select Name, Body, ContentType from Attachment where ParentId='a0b1100000K0TkKAAV'";
var fields = await client.QueryAsync<LeaseAttachment>(qry);
var fileContents = fields.records.FirstOrDefault<LeaseAttachment>();
byte[] bName = Convert.FromBase64String(fileContents.Body);
StreamWriter os = new StreamWriter("C:\\Users\\test\\Downloads" + "\\" + fName);
os.Write(bName);
os.Close();
Thanks,
Anu
Any possible solutions for our issues are highly appretiated !
If any additional requirements is needed please let me know.
Thanks in advance !