I'm working on a webservice to create new Salesforce Files. To validate the underlying methods, I manually uploaded a PNG file, which shows up in the file preview in Files.
I can retrieve the ContentVersion record via SOQL and create a new File, which does open correctly as an image if I download it and specify the application, but the image does not appear in the file preview. FileType is determined based on ContentURL and/or(?) PathOnClient, but these require the ContentVersion.Id, which doesn't exist until after the file is created, and cannot be edited.
Given a PNG with id 'originalImageId', I can retrieve attributes using the following:
String myId = 'originalImageId';
ContentVersion cv =
[SELECT Title, VersionData, ContentDocumentId,
ContentLocation, FileType
FROM ContentVersion
WHERE ContentDocumentId = :myId
AND IsLatest = true];
String encodedBlob = EncodingUtil.base64Encode(cv.VersionData);
String newId = FileManager.createFile(cv.Title, encodedBlob, cv.FileType);
which calls
public class FileManager {
public static Id createFile(String fileName, String base64Data,
String fileType, Id contentDocumentId){
base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8') ;
ContentVersion cv = new ContentVersion();
cv.ContentLocation = 'S'; // 'S' = a Salesforce File
cv.ContentDocumentId = contentDocumentId;
cv.VersionData = EncodingUtil.base64Decode(base64Data);
cv.Title = fileName;
// path will be different for Production
String path = 'https://nxstage--qa--c.cs92.content.force.com/sfc/servlet.shepherd/version/download';
cv.PathOnClient = path;
Utils.DatabaseInsert(cv);
Utils.debug('The contentDocumentId for ' + fileName + ' is ' + cv.ContentDocumentId);
return cv.Id;
}
public static Id createFile(String fileName, String base64Data,
String fileType){
String newId = createFile(fileName, base64Data, fileType, null);
Utils.debug('The ContentVersion.Id of ' + fileName + ' is ' + newId);
return newId;
}
Is there a trick to setting PathOnClient at create time / on insert that will allow me to specify the filetype?
Best Answer
OK, I got this to work. The key to getting the FileType set correctly and thus a preview generated is to ensure that the proper file extension is set via
ContentVersion.PathOnClient
.Additionally, while it may be necessary in your final web service, the
base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8')
creates a bad version of the file data when used via anon apex as in your example. I figured this out because when I downloaded the preview-less files, they wouldn't open as images.I changed the signatures, queries and calls to include
ContentVersion.FileExtension
, and then setPathOnClient
to beTitle + '.' + FileExtension
as I said in my comment above.The resulting
FileManager
class is then:And the anonymous block: