You need to sign in to do that
Don't have an account?
juventuss
Attaching a file to salesforce via the API
Could someone point me or possibly paste a sample of how to convert a file to base64 and upload to an opportunity under salesforce.com.
I've looked though previous questions in regards to this issue and most of them are quite old. Thank you
I've looked though previous questions in regards to this issue and most of them are quite old. Thank you
Hi juventuss,
There is an example of how to do this in the Sforce Explorer available here:
http://prdownloads.sourceforge.net/sforce/sforceExplorerSetup.zip?download
I downloaded the sample but i cant seem to figure out how it uploads a file. all i can do is select a file for download or for opening.
Hi juventuss,
This is the function that uploads the document. As you can see from the code, you simply open the document for reading and read the document into a byte array. You then set the value of the body property of the document object to the byte array. Set a couple of other simple properties like name and keywords and send the document object in a create call.
Private Sub CreateDocument(ByVal docPath As String)
Dim doc As New sforce.Document
Dim fi As System.IO.FileInfo = New System.IO.FileInfo(docPath)
If fi.Length > 5000000 Then
System.Windows.Forms.MessageBox.Show("This file is too big. The maximum document size is 5 MB.", "Document Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
doc.Name = fi.Name
doc.Description = fi.FullName
doc.FolderId = CType(Me.cboFolders.SelectedItem, ComboFolderItem).Folder.Id
Dim fs As System.IO.FileStream = System.IO.File.OpenRead(docPath)
Dim buffer() As Byte
ReDim buffer(Convert.ToInt32(fi.Length))
fs.Read(buffer, 0, buffer.Length)
doc.Body = buffer
Dim sr As sforce.SaveResult = binding.create(New sforce.sObject() {doc})(0)
If sr.success Then
Me.LoadDocs(doc.FolderId)
Else
MessageBox.Show("There was an error creating the document." & System.Environment.NewLine + System.Environment.NewLine + "Message: " + sr.errors(0).message)
End If
End If
End Sub
Hi,
I need to use an attachment also. I look at the sample and saw a definition which i cant do with my web service:
Dim Attach As New sforce.Attachment
This a compilation error since sforce doesnt have the "Attachment" object.
I"m using the partner wsdl and adding Contacts using Xml
How can i add an attachment using the partner wsdl?
Thanks
Shared Sub button3_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim binding As sforceP.SforceService = New sforceP.SforceService
Dim lr As sforceP.LoginResult = binding.login("username", "password")
binding.SessionHeaderValue = New sforceP.SessionHeader
binding.SessionHeaderValue.sessionId = lr.sessionId
binding.Url = lr.serverUrl
Dim OFD As New System.Windows.Forms.OpenFileDialog
Dim doc As sforceP.sObject = New sforceP.sObject
If OFD.ShowDialog().Equals(DialogResult.OK) Then
Dim fi As System.IO.FileInfo = New System.IO.FileInfo(OFD.FileName)
If fi.Length > 5000000 Then
System.Windows.Forms.MessageBox.Show("This file is too big. The maximum document size is 5 MB.", "Document Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument
Dim any(4) As System.Xml.XmlElement
doc.Any = any
doc.Any(0) = xmlDoc.CreateElement("Name")
doc.Any(0).InnerText = fi.Name
doc.Any(1) = xmlDoc.CreateElement("Description")
doc.Any(1).InnerText = fi.FullName
doc.Any(2) = xmlDoc.CreateElement("FolderId")
doc.Any(2).InnerText = "00l30000000ePKd"
doc.type = "Document"
Dim fs As System.IO.FileStream = System.IO.File.OpenRead(OFD.FileName)
Dim buffer(Convert.ToInt32(fi.Length)) As Byte
fs.Read(buffer, 0, buffer.Length)
doc.Any(3) = xmlDoc.CreateElement("Body")
doc.Any(3).InnerText = Convert.ToBase64String(buffer)
Dim sr As sforceP.SaveResult = binding.create(New sforceP.sObject() {doc})(0)
If (sr.success) Then
MessageBox.Show("Successfully create the document.")
Else
MessageBox.Show("There was an error creating the document." + System.Environment.NewLine + System.Environment.NewLine + "Message: " + sr.errors(0).message)
End If
'We can do a similar thing for an attachment
Dim attach As sforceP.sObject = New sforceP.sObject
attach.type = "Attachment"
attach.Any = any
attach.Any(0) = xmlDoc.CreateElement("Name")
attach.Any(0).InnerText = fi.Name
attach.Any(1) = xmlDoc.CreateElement("IsPrivate")
attach.Any(1).InnerText = "false"
attach.Any(2) = xmlDoc.CreateElement("ParentId")
attach.Any(2).InnerText = "00130000000iEjv"
attach.Any(3) = xmlDoc.CreateElement("Body")
attach.Any(3).InnerText = Convert.ToBase64String(buffer)
sr = binding.create(New sforceP.sObject() {attach})(0)
If (sr.success) Then
MessageBox.Show("Successfully create the attachment on an account.")
Else
MessageBox.Show("There was an error creating the attachment." + System.Environment.NewLine + System.Environment.NewLine + "Message: " + sr.errors(0).message)
End If
End If
End If
End Sub
Now, in C#
private void button3_Click(object sender, System.EventArgs e)
{
sforceP.SforceService binding = new sforceP.SforceService();
sforceP.LoginResult lr = binding.login("username", "paassword");
binding.SessionHeaderValue = new sforceP.SessionHeader();
binding.SessionHeaderValue.sessionId = lr.sessionId;
binding.Url = lr.serverUrl;
sforceP.sObject doc = new sforceP.sObject();
if (this.OFD.ShowDialog().Equals(DialogResult.OK))
{
System.IO.FileInfo fi = new System.IO.FileInfo(OFD.FileName);
if (fi.Length > 5000000)
{
System.Windows.Forms.MessageBox.Show("This file is too big. The maximum document size is 5 MB.", "Document Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
doc.Any = new System.Xml.XmlElement[4];
doc.Any[0] = xmlDoc.CreateElement("Name");
doc.Any[0].InnerText = fi.Name;
doc.Any[1] = xmlDoc.CreateElement("Description");
doc.Any[1].InnerText = fi.FullName;
doc.Any[2] = xmlDoc.CreateElement("FolderId");
doc.Any[2].InnerText = "00l30000000ePKd";
doc.type = "Document";
System.IO.FileStream fs = System.IO.File.OpenRead(OFD.FileName);
byte[] buffer = new byte[fi.Length];
fs.Read(buffer, 0, buffer.Length);
doc.Any[3] = xmlDoc.CreateElement("Body");
doc.Any[3].InnerText = Convert.ToBase64String(buffer);
sforceP.SaveResult sr = binding.create(new sforceP.sObject[] {doc})[0];
if (sr.success)
{
MessageBox.Show("Successfully create the document.");
}
else
{
MessageBox.Show("There was an error creating the document." + System.Environment.NewLine + System.Environment.NewLine + "Message: " + sr.errors[0].message);
}
//We can do a similar thing for an attachment
sforceP.sObject attach = new sforceP.sObject();
attach.type = "Attachment";
attach.Any = new System.Xml.XmlElement[4];
attach.Any[0] = xmlDoc.CreateElement("Name");
attach.Any[0].InnerText = fi.Name;
attach.Any[1] = xmlDoc.CreateElement("IsPrivate");
attach.Any[1].InnerText = "false";
attach.Any[2] = xmlDoc.CreateElement("ParentId");
attach.Any[2].InnerText = "00130000000iEjv";
attach.Any[3] = xmlDoc.CreateElement("Body");
attach.Any[3].InnerText = Convert.ToBase64String(buffer);
sr = binding.create(new sforceP.sObject[] {attach})[0];
if (sr.success)
{
MessageBox.Show("Successfully create the attachment on an account.");
}
else
{
MessageBox.Show("There was an error creating the attachment." + System.Environment.NewLine + System.Environment.NewLine + "Message: " + sr.errors[0].message);
}
}
}
}
I tried using part of the code but i keep getting an error on these lines.
Dim doc as sforce.object = new sforce.object (ERROR:Ne cannot be used on a class that is declared "MustInherit')
doc.any = any
doc.Any(0) = xmlDoc.CreateElement("Name")
doc.Any(0).InnerText = fi.Name
doc.Any(1) = xmlDoc.CreateElement("Description")
doc.Any(1).InnerText = fi.FullName
doc.Any(2) = xmlDoc.CreateElement("FolderId")
doc.Any(2).InnerText = "00l30000000ePKd"
doc.type = "Document"
(ERROR: Any is not a member of 'Saleforce_conector.sforce.sobject')
is there an import,include that i'm missing ?
Thank you.
Hi juventuss,
Is your intellisense not working?????
Dim doc as sforce.sObject = new sforce.sObject
Notice that is is sObject not object!
Add these two functions to your project. (It's in VB I'll send you the C# if you like)
You will have to change the name of the global object: GlobalSforce to the name of your sforce50 object. Just call the function with the ID of the Opportunity, the complete file name of the string and the name of the attachment.
Cheers;
GlennW
Public Function loadAttachement(ByVal id As String, ByVal filename As String, ByVal showName As String) As Boolean
Dim xdoc As New Xml.XmlDocument
Dim updateFields() As Xml.XmlElement
Dim updateObject As Sforce30.sObject
Dim updateObjects(0) As Sforce30.sObject
Dim sfResults() As Sforce30.SaveResult
Dim idx As Integer
Dim fileInfo As System.IO.FileInfo
fileInfo = New System.IO.FileInfo(filename)
ReDim Preserve updateFields(2)
updateFields(0) = xdoc.CreateElement("ParentId")
updateFields(0).InnerText = id
updateFields(1) = xdoc.CreateElement("Name")
updateFields(1).InnerText = showName
updateFields(2) = xdoc.CreateElement("Body")
updateFields(2).InnerText = getFileBase64String(filename)
updateObject = New Sforce30.sObject
updateObject.type = "Attachment"
updateObject.Any = updateFields
updateObjects(0) = updateObject
Try
sfResults = globalSForce.create(updateObjects)
Catch soapEx As System.Web.Services.Protocols.SoapException
Return False
Catch ex As Exception
Return False
End Try
Return True
End Function
Private Function getFileBase64String(ByVal objFileName As String) As String
Dim inFile As System.IO.FileStream
Dim binaryData() As Byte
Dim bytesRead As Long
Dim base64String As String = ""
inFile = New System.IO.FileStream(objFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)
ReDim binaryData(inFile.Length)
bytesRead = inFile.Read(binaryData, 0, inFile.Length)
inFile.Close()
base64String = System.Convert.ToBase64String(binaryData, 0, binaryData.Length)
Return base64String
End Function
I added that code in but i get an error here
updateObject = New sforce.sObject 'New' cannot be used on a class that is declared 'MustInherit'
updateObject.type = "Attachment" 'type' is not a member of 'salesforce_connector.sforce.sObject'
updateObject.Any = updateFields
updateObjects(0) = updateObject
Thanks for your assistance thus far.
I knew it was going to be an easy fix. ahhh..
Here is my code
Thanks for the help so far
Public Function loadAttachement(ByVal id As String, ByVal filename As String, ByVal showName As String) As Boolean
Dim xdoc As New Xml.XmlDocument
Dim updateFields() As Xml.XmlElement
Dim binding As sforce1.SforceService = New sforce1.SforceService
Dim updateObject As sforce1.sObject
Dim updateObjects(0) As sforce1.sObject
Dim sfResults() As sforce1.SaveResult
Dim idx As Integer
Dim fileInfo As System.IO.FileInfo
fileInfo = New System.IO.FileInfo(filename)
If fileInfo.Length > 5000000 Then
System.Windows.Forms.MessageBox.Show("This file is too big. The maximum document size is 5 MB.", "Document Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
ReDim Preserve updateFields(2)
updateFields(0) = xdoc.CreateElement("ParentId")
updateFields(0).InnerText = id
updateFields(1) = xdoc.CreateElement("Name")
updateFields(1).InnerText = fileInfo.Name
updateFields(2) = xdoc.CreateElement("Body")
updateFields(2).InnerText = getFileBase64String(filename)
updateObject = New sforce1.sObject
updateObject.type = "Attachment"
updateObject.Any = updateFields
updateObjects(0) = updateObject
Try
sfResults = binding.create(updateObjects)
Catch soapEx As System.Web.Services.Protocols.SoapException
Return False
Catch ex As Exception
Return False
End Try
Return True
End If
End Function
The flag indicates nothing. I look at my network traffic and packets are moving though but nothing gets attached. Quite confusing.
Can you post your finalized code ?
Public Function loadAttachement(ByVal id As String, ByVal filename As String, ByVal showName As String) As Boolean
Dim xdoc As New Xml.XmlDocument
Dim updateFields() As Xml.XmlElement
Dim binding As sforce1.SforceService = New sforce1.SforceService
Dim updateObject As sforce1.sObject
Dim updateObjects(0) As sforce1.sObject
Dim sfResults() As sforce1.SaveResult
Dim idx As Integer
Dim fileInfo As System.IO.FileInfo
fileInfo = New System.IO.FileInfo(filename)
If fileInfo.Length > 5000000 Then
System.Windows.Forms.MessageBox.Show("This file is too big. The maximum document size is 5 MB.", "Document Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
ReDim Preserve updateFields(2)
updateFields(0) = xdoc.CreateElement("ParentId")
updateFields(0).InnerText = id
updateFields(1) = xdoc.CreateElement("Name")
updateFields(1).InnerText = fileInfo.Name
updateFields(2) = xdoc.CreateElement("Body")
updateFields(2).InnerText = getFileBase64String(filename)
updateObject = New sforce1.sObject
updateObject.type = "Attachment"
updateObject.Any = updateFields
updateObjects(0) = updateObject
Try
frmwksheet.DefInstance.lblsaveinfo.Visible = True
frmwksheet.DefInstance.lblsaveinfo.Text = "Saving to salesforce"
sfResults = binding.create(updateObjects)
frmwksheet.DefInstance.lblsaveinfo.Visible = False
Catch soapEx As System.Web.Services.Protocols.SoapException
Return False
Catch ex As Exception
Return False
End Try
Return True
End If
End Function
Private Function getFileBase64String(ByVal objFileName As String) As String
Dim inFile As System.IO.FileStream
Dim binaryData() As Byte
Dim bytesRead As Long
Dim base64String As String = ""
inFile = New System.IO.FileStream(objFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)
ReDim binaryData(inFile.Length)
bytesRead = inFile.Read(binaryData, 0, inFile.Length)
inFile.Close()
base64String = System.Convert.ToBase64String(binaryData, 0, binaryData.Length)
Return base64String
End Function
if not sfResults[0].success then
throw new Exception(sfResults[0].Errors[0].Message);
end if
It might be worth your while to work through the samples in the docs.
An unhandled exception of type 'System.Net.WebException' occurred in system.web.services.dll
Additional information: The underlying connection was closed: An unexpected error occurred on a receive.
This is the code i have.
Dim binding As sforce1.SforceService = New sforce1.SforceService
binding.SessionHeaderValue = New sforce1.SessionHeader
binding.SessionHeaderValue.sessionId = frmlogin.DefInstance.lblsession.Text
binding.Url = "http://na1.salesforce.com/services/Soap/u/5.0"
Dim fileInfo As System.IO.FileInfo
Dim OFD As New System.Windows.Forms.OpenFileDialog
Dim sr As sforce1.SaveResult
If OFD.ShowDialog().Equals(DialogResult.OK) Then
Dim fi As System.IO.FileInfo = New System.IO.FileInfo(filename)
fileInfo = New System.IO.FileInfo(filename)
If fileInfo.Length > 5000000 Then
System.Windows.Forms.MessageBox.Show("This file is too big. The maximum document size is 5 MB.", "Document Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim fs As System.IO.FileStream = System.IO.File.OpenRead(filename)
Dim buffer(Convert.ToInt32(fi.Length)) As Byte
fs.Read(buffer, 0, buffer.Length)
Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument
Dim any(4) As System.Xml.XmlElement
Dim attach As sforce1.sObject = New sforce1.sObject
attach.type = "Attachment"
attach.Any = any
attach.Any(0) = xmlDoc.CreateElement("Name")
attach.Any(0).InnerText = fi.Name
attach.Any(1) = xmlDoc.CreateElement("IsPrivate")
attach.Any(1).InnerText = "false"
attach.Any(2) = xmlDoc.CreateElement("ParentId")
attach.Any(2).InnerText = id
attach.Any(3) = xmlDoc.CreateElement("Body")
attach.Any(3).InnerText = Convert.ToBase64String(buffer)
sr = binding.create(New sforce1.sObject() {attach})(0)
If (sr.success) Then
MessageBox.Show("Successfully create the attachment on an account.")
Else
MessageBox.Show("There was an error creating the attachment." + System.Environment.NewLine + System.Environment.NewLine + "Message: " + sr.errors(0).message)
End If
End If
End If
seems http and https are used randomly to transfer files
Hi can i get an C# code for uploading the attachment. I am a newbie and i haven't worked on VB at all
Hi Juventuss.
That's very nice of you to share the code.
U
nfortunately, I am not a programmer, so I don't know what to do with the code alone.
Can you give me also the instructions on how to make this code work?
Now the problem I am facing is, I am not able to parse and save the InnerText as docx file and save it locally. :(
Can someone guide me how to decode the InnerText content and save it as docx file from C#.
string SOQL = "SELECT Id, Name, Body FROM Document where Id = '" + id + "'";
QueryResult queryResult = SfdcBinding.query(SOQL);
// below line not working. Tried other encodings also but no success.
byte[] filebytes = Encoding.ASCII.GetBytes(queryResult.records[0].Any[2].InnerText);
File.WriteAllBytes(localfilepath, filebytes);