2

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:

  1. Insert new ContentVersion with base64 encoded VersionData, Title and PathOnClient
  2. Find ContentDocument related to ContentVersion just created "Select ContentDocumentId FROM ContentVersion WHERE Id = taken from step 1"
  3. 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?

Content document

Opportunity

enter image description here

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);
  • Do you have an Contact that has been linked via the UI you could compare it with? – Daniel Ballinger Feb 27 '17 at 22:29
  • Looking at ContentDocumentLink I see there is also a Visibility field. Maybe set that to AllUsers or SharedUsers? – Daniel Ballinger Feb 27 '17 at 22:34
  • Try setting Origin = 'H' for ContentVersion – o-lexi Feb 28 '17 at 1:48
  • @minige do you mind sharing your code? – Mahmood Mar 6 '17 at 19:54
  • @Mahmood, the source id attached – Mike Raven Mar 6 '17 at 22:29
1

I used the Salesforce UI to add a File to an Opportunity. Then checked the resulting ContentDocumentLink records with SQOL.

Select Id,LinkedEntityId,ContentDocumentId,IsDeleted,ShareType,Visibility from ContentDocumentLink where ContentDocumentId = '0694000000548HHAAY'

ContentDocumentLink

Note how there are two records, one to the Opportunity and one to my user record (this will be why you can't see it in your private library). The one to the Opportunity has the ShareType V (Viewer permission) and Visibility AllUsers

  • 1
    I tried to change Visibility field and that didn't help. Also another ContentDocumentLink (linked to a User object) is created automatically with ContentDocument, so we don't need to create it. – Mike Raven Feb 28 '17 at 2:41
  • I'll try again when I get a chance to see what happens if I create the records via the API. – Daniel Ballinger Feb 28 '17 at 3:44
1

The Visibility field has affect if Communities are enabled. A visibility of AllUsers means both 'internal' uses and community users can see the file if they have access to the record, whereas a visibility of InternalOnly means only internal users can see it. Shared user visibility isn't applicable to record shares. It applies to shares to a user if User Sharing is set to private in an org.

Your steps look correct. How did you verify "... Content element is not linked to the opportunity and I can't see it in my private library?"

After step 1, the file would appear in the 'private library' filter because it is private. After step 3, it should no longer appear in the 'private library' filter if it is shared with the opportunity, because it is no longer private. If inserting the CDL worked, and it isn't showing in the 'private library' filter, it seems like the file is shared with the opportunity.

I would suggest querying the ContentDocumentLink table as Daniel did, and if you see 2 CDLs, one to the owner and one to the opportunity, it looks correct to me.

Another test is to go to the File detail page (going to salesforce.com/069...) and opening up the 'sharing settings' dialog to see if it shows it Shared with the opportunity that way.

Please report back the results of the CDL query and the 'sharing settings' dialog.

Also, you can add both the "Notes and Attachments" and "Files" related lists to the opportunity and the file should appear in both if it is linked.

I would suggest looking at the sharing settings dialog and the related lists in the Classic UI (although it should work the same in Lightning).

If you see an inconsistency in one of these places, please let me know, as there may be a bug.

  • Thank for feedback, Neil. I updated my post with pictures (Content Document, Opportunity in Classic, Opportunity in Lightning). Answering to your question: yes, I can navigate to Content Document (and it's marked as linked to my Opportunity) and I see it in Lightning but don't see it in Classic (both pictures are attached) – Mike Raven Mar 6 '17 at 22:53
  • @minige you need to check this answer, and I don't see files related list on your SF Classic picture screenshot. Do you have it on your page layout? – Mahmood Mar 7 '17 at 7:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.