File management API
View a list of namespaces for file management API in the table below.
Namespace | Description |
---|---|
Terrasoft.File.Abstractions | Determines the file management logic in Creatio. |
Terrasoft.File | Implements the abstractions used in Creatio. |
File locators
A file locator determines the file location and implements the Terrasoft.File.Abstractions.IFileLocator
interface. A file locator must contain a unique file identifier: RecordId
.
Creatio lets you create different file locators for different file storages. Depending on the file storage, the file locator might have extra properties to identify the file location. For example, the Terrasoft.File.EntityFileLocator
class implements the file locator for the current file storage. View the properties of the EntityFileLocator
object in the table below.
Property | Description |
---|---|
RecordId | Includes a unique file identifier. |
EntitySchemaName | Includes the name of the object schema where the file is stored. For example, "ActivityFile," "CaseFile." |
File structure
File in Creatio implements the Terrasoft.File.Abstractions.IFile
interface whose methods let you manage files asynchronously, regardless of the file storage type. The Terrasoft.File.Abstractions.FileUtils
class implements methods to manage files synchronously.
View the file structure supported by Creatio in the table below.
Structure element | Description | Storage |
---|---|---|
Metadata | File metadata includes file properties, such as file name, file size in bytes, file creation date. File metadata is based on the | The storage that implements the |
Content | File content. | The storage that implements the |
The implementations of the Terrasoft.File.Abstractions.Metadata.IFileMetadataStorage
and Terrasoft.File.Abstractions.Metadata.IFileContentStorage
interfaces include specific features to interact with different file storages, such as server's file system, S3 file storage, Azure Blob file storage, Google Drive, etc.
Operations with files
Access an existing file and create a new file
The Terrasoft.File.Abstractions.IFileFactory
interface implements methods to create and retrieve objects of a class that implements the Terrasoft.File.Abstractions.IFile
interface. To access the Terrasoft.File.Abstractions.IFileFactory
interface, use the methods of the Terrasoft.File.File.FileFactoryUtils
class that extends the UserConnection
class. Therefore, file management requires an instance of the UserConnection
or SystemUserConnection
class.
Since the file locator determines the file location, specify the RecordId
file identifier to access an existing file.
View the examples that access existing files below.
- Access the existing file (option 1)
- Access the existing file (option 2)
/* Retrieve the instance of the file factory. */
IFileFactory fileFactory = UserConnection.GetFileFactory();
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator = new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the factory method. */
IFile file = fileFactory.Get(fileLocator);
/* Implement the business logic that works with the file and its contents using instance of a class that implements the "IFile" interface. */
...;
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator = new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile file = UserConnection.GetFile(fileLocator);
/* Implement the business logic that works with the file and its contents using instance of a class that implements the "IFile" interface. */
...;
To create a new file:
- Create a
RecordId
file identifier. - Specify the file identifier in the method that creates the file locator.
View the examples that create new files below.
- Create a new file (option 1)
- Create a new file (option 2)
/* Retrieve the instance of the file factory. */
IFileFactory fileFactory = UserConnection.GetFileFactory();
/* Create a unique ID for the new file. */
Guid recordId = Guid.NewGuid();
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator = new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the factory method. */
IFile file = fileFactory.Create(fileLocator);
/* Implement the business logic that works with the file and its contents using instance of a class that implements the "IFile" interface. */
...;
/* Create a unique ID for the new file. */
Guid recordId = Guid.NewGuid();
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator = new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile file = UserConnection.CreateFile(fileLocator);
/* Implement the business logic that works with the file and its contents using instance of a class that implements the "IFile" interface. */
...;
View the examples that execute CRUD operations with the files below.
Create a new file bound to a single activity
/* Create a unique ID for the new file. */
Guid recordId = Guid.NewGuid();
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator= new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile file = UserConnection.CreateFile(fileLocator);
/* Specify the file name to determine the file in the file storage. */
file.Name = "Some name of a new";
/* Bind the file to a single activity using "activityId." */
file.SetAttribute("ActivityId", activityId);
/* Save the file metadata before saving the file content. */
file.Save();
/* Specify the file content. */
var content = new byte[] {0x12, 0x34, 0x56};
using (var stream = new MemoryStream(content)) {
/* Save the file content to the database. Specify "FileWriteOptions.SinglePart" to save the content without breaking it into multiple parts. */
file.Write(stream, FileWriteOptions.SinglePart);
}
Retrieve the file content
/* The file content. */
var content = new byte[]();
/* Create a unique ID for the new file. */
Guid recordId = Guid.NewGuid();
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator = new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile file = UserConnection.GetFile(fileLocator);
using (Stream stream = file.Read()) {
/* Retrieve the file content and save it to the array. */
content = stream.ReadToEnd();
}
Copy a file from the original file storage, paste the file to a new file storage, and delete the file from the original file storage
/* The file content. */
var content = new byte[]();
/* Create the "EntityFileLocator" instance identified by "recordId" and stored in the "ActivityFile" database table. */
var fileLocator = new EntityFileLocator("ActivityFile", recordId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile file = UserConnection.GetFile(fileLocator);
/* Retrieve the file content and save it to the array. */
using (Stream stream = file.Read()) {
content = stream.ReadToEnd();
}
/* Create a unique ID to copy the current file. */
Guid copyFileId = Guid.NewGuid();
/* Create the "EntityFileLocator" instance identified by "copyFileId" and stored in the "ActivityFile" database table. */
var copyFileLocator = new EntityFileLocator("ActivityFile", copyFileId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile copyFile = UserConnection.CreateFile(copyFileLocator);
/* Specify the file name to determine the file in a new file storage. */
copyFile.Name = file.Name + " - Copy";
/* Save the file metadata before saving the file content. */
copyFile.Save();
/* Copy the file content from the original file using one of the options.
Option 1. Specify "FileWriteOptions.SinglePart" to save the content without breaking it into multiple parts. */
copyFile.Write(new MemoryStream(content), FileWriteOptions.SinglePart);
/* Option 2. */
file.Copy(copyFile); */
/* Create a unique ID to paste the copied file. */
Guid moveFileId = Guid.NewGuid();
/* Create the "EntityFileLocator" instance identified by "moveFileId" and stored in the "ContactFile" database table. */
var moveFileLocator = new EntityFileLocator("ContactFile", moveFileId);
/* Pass the created locator to the method of the "UserConnection" class. */
IFile moveFile = UserConnection.CreateFile(moveFileLocator);
/* Save the file metadata before saving the file content. */
moveFile.Save();
/* Paste the copied file to a new file storage. */
file.Move(moveFile);
/* Delete the file from original file storage. */
file.Delete();
Implement a custom file storage
Implement custom file storage if the current file metadata storage is insufficient for your business goals. To do this:
- Implement the
Terrasoft.File.Abstractions.Content.IFileContentStorage
interface that describes the API required for working with the file storage. - Implement a custom metadata storage that implements the
Terrasoft.File.Abstractions.Metadata.IFileMetadataStorage
interface. - Inherit the metadata class from the
Terrasoft.File.Abstractions.Metadata.FileMetadata
class. - Implement a custom file locator that implements the
Terrasoft.File.Abstractions.IFileLocator
interface. - Register a custom metadata storage in the SysFileMetadataStorage lookup.
- Register a custom content storage in the SysFileContentStorage lookup.
View the example that creates file content storage in the file system below.
namespace Terrasoft.Configuration {
using System.IO;
using System.Threading.Tasks;
using Terrasoft.File.Abstractions;
using Terrasoft.File.Abstractions.Content;
using Terrasoft.File.Abstractions.Metadata;
using Terrasoft.File.Metadata;
/* Class that implements the "IFileContentStorage" interface. */
public class FsFileBlobStorage: IFileContentStorage {
/* A root path to the storage. */
private const string BaseFsPath = "C:\\FsStore\\";
private static string GetPath(FileMetadata fileMetadata) {
var md = (EntityFileMetadata)fileMetadata;
string key = $"{md.EntitySchemaName}\\{md.RecordId}_{fileMetadata.Name}";
return Path.Combine(BaseFsPath, key);
}
public Task<Stream> ReadAsync(IFileContentReadContext context) {
string filePath = GetPath(context.FileMetadata);
Stream stream = System.IO.File.OpenRead(filePath);
return Task.FromResult(stream);
}
public async Task WriteAsync(IFileContentWriteContext context) {
string filePath = GetPath(context.FileMetadata);
FileMode flags = context.WriteOptions != FileWriteOptions.SinglePart
? FileMode.Append
: FileMode.OpenOrCreate;
string dirPath = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dirPath)) {
Directory.CreateDirectory(dirPath);
}
using (var fileStream = System.IO.File.Open(filePath, flags)) {
context.Stream.CopyToAsync(fileStream);
}
}
public Task DeleteAsync(IFileContentDeleteContext context) {
string filePath = GetPath(context.FileMetadata);
System.IO.File.Delete(filePath);
return Task.CompletedTask;
}
public Task CopyAsync(IFileContentCopyMoveContext context) {
string sourceFilePath = GetPath(context.SourceMetadata);
string targetFilePath = GetPath(context.TargetMetadata);
System.IO.File.Copy(sourceFilePath, targetFilePath);
return Task.CompletedTask;
}
public Task MoveAsync(IFileContentCopyMoveContext context) {
string sourceFilePath = GetPath(context.SourceMetadata);
string targetFilePath = GetPath(context.TargetMetadata);
System.IO.File.Move(sourceFilePath, targetFilePath);
return Task.CompletedTask;
}
}
}
File management exceptions
Exception type | Message | Exception conditions |
---|---|---|
Terrasoft.File.Abstractions.FileNotFoundByLocatorException | File not found by locator | When accessing any properties or methods of the |
System.InvalidOperationException | Can't delete new file: | When deleting a newly created file. I. e., |
Terrasoft.Common.NullOrEmptyException | File name cannot be null or empty | When saving a file that has the |
System.InvalidOperationException | Can't find a metadata storage for the | If a file metadata storage corresponding to the locator type is not found. |
System.InvalidOperationException | Can't find a content storage for the | If a file content storage corresponding to the file metadata storage is not found. |
Content storage | If a selected content storage is disabled. |