I'm trying to find a way how to upload content document and link it to Salesforce object (say, an opportunity) programmatically (using SOAP API). That's what I tried:
- Insert new ContentVersion with base64 encoded VersionData, Title and PathOnClient
- Find ContentDocument related to ContentVersion just created "Select ContentDocumentId FROM ContentVersion WHERE Id = taken from step 1"
- Insert new ContentDocumentLink with ContentDocumentId = "taken from step 2", Share Type = "I" (inherited from Opportunity), LinkedEntityId = "my opportunity id"
All the operations completed successfully. I can see the Opportunity with linked file in Lightning Experience, however, can't see the file in SF Classic and I can't see it in my private library either. But I can navigate to the Content using its Id (so it's definitely created in Salesforce).
- Pic1 shows (LEX) Opportunity and linked files.
- Pic2 shows (SF Classic) same opportunity but no files are visible.
Did I miss any important step?
The source code (C#, Web Reference using Partner WSDL. Login, error handling is omitted):
// create content version
XmlDocument docCreateContentVersion = new XmlDocument();
XmlElement[] xmlCreateContentVersion = new XmlElement[3];
xmlCreateContentVersion[0] = docCreateContentVersion.CreateElement("VersionData");
xmlCreateContentVersion[0].InnerText = System.Convert.ToBase64String(Encoding.ASCII.GetBytes("Hello, World"));
xmlCreateContentVersion[1] = docCreateContentVersion.CreateElement("Title");
xmlCreateContentVersion[1].InnerText = "My Test Document";
xmlCreateContentVersion[2] = docCreateContentVersion.CreateElement("PathOnClient");
xmlCreateContentVersion[2].InnerText = "My Test Document";
sObject createContentVersion = new sObject();
createContentVersion.type = "ContentVersion";
createContentVersion.Any = xmlCreateContentVersion;
SaveResult[] createContentVersionResults = binding.create(new sObject[] { createContentVersion });
// obtain content documents
QueryResult contentDocuments = binding.query("SELECT ContentDocumentId, PublishStatus, OwnerId FROM ContentVersion WHERE Id = '" + createContentVersionResults[0].id + "'");
String contentDocumentId = contentDocuments.records[0].Any[0].FirstChild.Value;
Console.WriteLine("ContentDocumentId="+contentDocumentId);
// create content document link
XmlDocument docCreateContentDocumentLink = new XmlDocument();
XmlElement[] xmlCreateContentDocumentLink = new XmlElement[3];
xmlCreateContentDocumentLink[0] = docCreateContentDocumentLink.CreateElement("ContentDocumentId");
xmlCreateContentDocumentLink[0].InnerText = contentDocumentId;
xmlCreateContentDocumentLink[1] = docCreateContentDocumentLink.CreateElement("LinkedEntityId");
xmlCreateContentDocumentLink[1].InnerText = "006j000000SYHGu";
xmlCreateContentDocumentLink[2] = docCreateContentDocumentLink.CreateElement("ShareType");
xmlCreateContentDocumentLink[2].InnerText = "I";
sObject createContentDocumentLink = new sObject();
createContentDocumentLink.type = "ContentDocumentLink";
createContentDocumentLink.Any = xmlCreateContentDocumentLink;
SaveResult[] createContentDocumentLinkResults = binding.create(new sObject[] { createContentDocumentLink });
Console.WriteLine("ContentDocumentLinkId=" + createContentDocumentLinkResults[0].id);
Visibility
field. Maybe set that to AllUsers or SharedUsers?Origin
= 'H' forContentVersion