Skip to main content
Version: 10

Manage files using Entity class

Level: intermediate

Creatio lets you manage files using the File API through the Entity class. The API supports CRUD operations for files stored either in the Creatio database or in external file storage, such as AWS S3 or Azure Blob storage. Learn more: File API.

Creatio uses the File API for all operations with file objects through the Entity class. For non-file objects, behavior remains unchanged.

We recommend storing files in external file storage instead of the database, regardless of the access method used (either the File API directly or via the Entity class). This can improve solution reliability, cost efficiency, and maintainability. Learn more: File storage (user documentation).

When managing file records using the File API through the Entity class, avoid specifying the SysFileStorageId, Size, and TotalSize properties explicitly. These values are managed by Creatio automatically for all CRUD operations.

Objects that store files​

Creatio stores files in dedicated objects. Each object corresponds either to a specific parent object or to a generic file storage model that can be used across multiple objects. The choice of an object determines how the file is linked to its parent object and which request parameters are required when working with the API.

The table below lists examples of objects used for file storage. The complete list of objects is available in Creatio. Objects that store files have the "File" suffix.

Object

Description

Parent object

"Uploaded file" (SysFile code)

Generic file storage.

Any object

"File and link of activity" (ActivityFile code)

Files attached to activities.

"Activity" (Activity code)

"Contact attachment" (ContactFile code)

Files attached to contacts.

"Contact" (Contact code)

"File and link of account" (AccountFile code)

Files attached to accounts.

"Account" (Account code)

"Attachments and notes detail object in Cases section" (CaseFile code)

Files attached to support cases.

"Case" (Case code)

"Order files" (OrderFile code)

Files attached to orders.

"Order" (Order code)

"File and link of opportunity" (OpportunityFile code)

Files attached to opportunities.

"Opportunity" (Opportunity code)

In most cases, you can store files using the generic "Uploaded file" (SysFile code) object, which is used automatically for custom apps. We recommend creating a dedicated file object for custom apps that are expected to store a large number of files or require separate file management for a specific business scenario. This approach helps organize file storage better, improves scalability, and aligns with how Creatio implements file storage in some out-of-the-box apps.

Identify file objects​

To check whether an "Object" type schema is a file object, use the following code:

Check whether an "Object" type schema represents a file object
EntitySchema schema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");
bool isFile = schema.IsFile;

If schema.IsFile == true, the "Object" type schema represents a file object, and Creatio lets you manage files using the File API through the Entity class.

Usage examples​

Create a file​

The Entity class provides several methods for writing binary file content to the "Data" column. Choose the appropriate method based on the business goals listed in the table below.

Business goal

Method

Write file content as a byte array.

void SetBytesValue(string valueName, byte[] streamBytes)

Parameters

Parameter

Description

valueName

The name of the object column that stores binary file content.

streamBytes

The binary file content.

Write file content as a stream, for example, to pass a file received from a request or another API.

bool SetStreamValue(string valueName, Stream value)

Parameters

Parameter

Description

valueName

The name of the object column that stores binary file content.

value

The stream that contains binary file content.

Write file content using the generic column setter.

bool SetColumnValue(string valueName, object value)

Parameters

Parameter

Description

valueName

The name of the object column that stores binary file content.

value

The binary file content as a non-empty byte[] value.

Since version 10.1, you can use these methods interchangeably, including for file records that you load from the database using the FetchFromDB() method. The Save() method saves the content passed by the last call of any of these methods, regardless of the storage that contains the file. To read the new content before you call the Save() method, use the GetColumnValue() or GetTypedColumnValue<byte[]>() method. The GetBytesValue() and GetStreamValue() methods return only the content saved to the storage.

The SetColumnValue() method handles the value as file content only if all of the following conditions are met:

  • The object is a file object, i.e., the schema.IsFile property is true. Learn more: Identify file objects.
  • The column is the "Data" column.
  • The value is a non-empty byte[] value.

Otherwise, Creatio handles the value as a regular column value.

Do not call the SetColumnValue() method with the null value or an empty byte[] value to keep or clear file content. Depending on the storage that contains the file, Creatio either keeps the current content or saves empty content. To keep the current file content, do not set the "Data" column value. To clear the file content, call the SetBytesValue() method with the null value or an empty byte[] value, then call the Save() method.

The SetColumnValue() method returns false in the following cases:

  • You pass file content that is equal to the current content of an existing file record. In this case, Creatio ignores the call.
  • A ColumnValueChanging event handler cancels the change.

The following examples demonstrate different ways to create a file below.

Create a file with immediate data saving​

The following example creates a file record using the "Uploaded file" (SysFile code) object and saves the file content to the storage immediately below.

Create a file with immediate data saving
/* Create a file record using the "SysFile" object and save the file content to
the storage immediately. */
public bool CreateFileWithData(UserConnection userConnection)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Populate the record using default column values. */
fileEntity.SetDefColumnValues();

/* Set the file name. */
fileEntity.SetColumnValue("Name", "some-file-name.txt");

/* Convert the file content to a byte array. */
byte[] fileContent =
System.Text.Encoding.UTF8.GetBytes("Some file content");

/* Assign the binary file content to the "Data" column. */
fileEntity.SetBytesValue("Data", fileContent);

/* Save the file record and persist the content to the storage. */
bool result = fileEntity.Save();

/* Return the result of the save operation. */
return result;
}

Create a file with deferred data saving​

If you call the Save() method without writing file content first, only file metadata is created. The actual file content is saved to storage only after you write the file content and call the Save() method.

The following example creates a file record using the "Uploaded file" (SysFile code) object and saves only the file metadata below. The binary file content is added and persisted to the storage in a separate operation.

Create a file with deferred data saving
/* Create a file record using the "SysFile" object without saving file
content. */
public Guid CreateFileMetadataOnly(UserConnection userConnection)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Populate the record using default column values. */
fileEntity.SetDefColumnValues();

/* Set the file name. */
fileEntity.SetColumnValue("Name", "SomeFileName.pdf");

/* Save the file record metadata without file content. */
fileEntity.Save();

/* Return the ID of the created file record. */
return fileEntity.PrimaryColumnValue;
}

/* Add binary file content to an existing file record and save it to the
storage. */
public bool AddFileContent(UserConnection userConnection, Guid fileId)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Load the existing file record by its ID. */
if (!fileEntity.FetchFromDB(fileId))
{
return false;
}

/* Retrieve the file content as a byte array.
"GetPdfContent()" is a custom method that returns file content. */
byte[] fileContent = GetPdfContent();

/* Assign the binary file content to the "Data" column. */
fileEntity.SetBytesValue("Data", fileContent);

/* Save the file record and persist the content to the storage. */
return fileEntity.Save();
}

Create a file linked to a contact​

When working with file objects that have a master-detail relationship, for example, ContactFile, ActivityFile, the file record must be linked to its parent record explicitly. To do this, set the reference column value using the SetPropertyValue() method before saving the file record.

The following example creates a file record using the "Contact attachment" (ContactFile code) object, binds it to a contact record, and saves the file content to the storage below.

Create a file linked to a contact
/* Create a file record using the "ContactFile" object and bind it to a
contact. */
public bool CreateContactFile(UserConnection userConnection, Guid contactId)
{
/* Retrieve the "ContactFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("ContactFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Populate the record using default column values. */
fileEntity.SetDefColumnValues();

/* Set the file name. */
fileEntity.SetColumnValue("Name", "SomeContactPhoto.jpg");

/* Bind the file record to the contact record. */
fileEntity.SetPropertyValue("ContactId", contactId);

/* Retrieve the file content as a byte array.
"GetImageBytes()" is a custom method that returns image data. */
byte[] imageData = GetImageBytes();

/* Assign the binary file content to the "Data" column. */
fileEntity.SetBytesValue("Data", imageData);

/* Save the file record and persist the content to the storage. */
return fileEntity.Save();
}

Create a file using the generic SysFile object​

When working with the generic "Uploaded file" (SysFile code) file object, files are linked to parent records using a polymorphic relationship. Unlike object-specific file objects, SysFile can be linked to records of any object dynamically. In this case, the file record is associated with a parent object by specifying the following parameters before saving the file:

  • RecordSchemaName is the code of the parent "Object" type schema.
  • RecordId is the ID of the parent record to which the file is attached. Used together with RecordSchemaName to establish the link between the file and the target object.

The following example creates a file record using the "Uploaded file" (SysFile code) object, binds it to a parent record dynamically, and saves the file content to the storage below.

Create a file using the generic SysFile object
/* Create a file record using the "SysFile" object and bind it to a parent
record using a polymorphic relationship. */
public bool CreateSysFile(UserConnection userConnection, Guid recordId,
string schemaName)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Populate the record using default column values. */
fileEntity.SetDefColumnValues();

/* Set the file name. */
fileEntity.SetColumnValue("Name", "SomeFileName.pdf");

/* Bind the file record to the parent record by specifying the code of
the parent "Object" type schema and the ID of the parent record to which
the file is attached. */
fileEntity.SetColumnValue("RecordSchemaName", schemaName);
fileEntity.SetColumnValue("RecordId", recordId);

/* Retrieve the file content as a byte array.
"GetPdfContent()" is a custom method that returns file content. */
byte[] fileContent = GetPdfContent();

/* Assign the binary file content to the "Data" column. */
fileEntity.SetBytesValue("Data", fileContent);

/* Save the file record and persist the content to the storage. */
return fileEntity.Save();
}

Read a file​

The Entity class provides several methods for reading binary file content from the "Data" column. Choose the appropriate method based on the business goals listed in the table below. These methods return the content saved to the storage and do not return content that you write before calling the Save() method.

Business goal

Method

Read file content as a byte array.

byte[] GetBytesValue(string valueName)

Parameters

Parameter

Description

valueName

The name of the object column that stores binary file content.

Read file content as a stream, for example, to write it to a response or pass it to another API.

MemoryStream GetStreamValue(string valueName)

Parameters

Parameter

Description

valueName

The name of the object column that stores binary file content.

Read file content as a byte array​

The following example retrieves the binary content of an existing file record from the "Uploaded file" (SysFile code) object as a byte array below.

Read file content as a byte array
/* Retrieve the binary content of a file record as a byte array. */
public byte[] ReadFileContent(UserConnection userConnection, Guid fileId)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Load the existing file record by its ID. */
if (!fileEntity.FetchFromDB(fileId))
{
return null;
}

/* Retrieve the binary file content from the "Data" column as a byte
array. */
byte[] fileContent = fileEntity.GetBytesValue("Data");

/* Return the file content. */
return fileContent;
}

Read file content as a stream​

The following example retrieves the binary content of an existing file record from the "Uploaded file" (SysFile code) object as a stream below.

Read file content as a stream
/* Retrieve the binary content of a file record as a stream. */
public MemoryStream ReadFileAsStream(UserConnection userConnection, Guid fileId)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Load the existing file record by its ID. */
if (!fileEntity.FetchFromDB(fileId))
{
return null;
}

/* Retrieve the binary file content from the "Data" column as a stream. */
MemoryStream fileStream = fileEntity.GetStreamValue("Data");

/* Return the file stream. */
return fileStream;
}

Update a file​

To update file content, use the methods that write binary file content to the "Data" column. Learn more about the methods and their behavior: Create a file.

The following example updates the binary content of an existing file record using the "Uploaded file" (SysFile code) object below.

Update a file
/* Update the binary content of an existing file record. */
public bool UpdateFileContent(UserConnection userConnection, Guid fileId,
byte[] newContent)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Load the existing file record by its ID. */
if (!fileEntity.FetchFromDB(fileId))
{
return false;
}

/* Assign the new binary file content to the "Data" column. Since version
10.1, you can also call "SetColumnValue("Data", newContent)". */
fileEntity.SetBytesValue("Data", newContent);

/* Update the file name (optional). */
fileEntity.SetColumnValue("Name", "NewFileName.txt");

/* Save the file record and persist the updated content to the storage. */
return fileEntity.Save();
}

Delete a file​

When deleting a file record, both the file metadata and the corresponding binary content are removed automatically. This behavior ensures that no unreferenced files remain in the storage.

The following example deletes an existing file record created using the "Uploaded file" (SysFile code) object below.

Delete a file
/* Delete an existing file record along with its binary content. */
public bool DeleteFile(UserConnection userConnection, Guid fileId)
{
/* Retrieve the "SysFile" object. */
EntitySchema fileSchema =
userConnection.EntitySchemaManager.GetInstanceByName("SysFile");

/* Create a file record using the "Entity" class. */
Entity fileEntity = fileSchema.CreateEntity(userConnection);

/* Load the existing file record by its ID. */
if (!fileEntity.FetchFromDB(fileId))
{
return false;
}

/* Delete the file record. Both the metadata and the file content are
removed from the storage. */
bool result = fileEntity.Delete();

/* Return the result of the delete operation. */
return result;
}

See also​

File API

Manage the database records

Data access through ORM

File storage (user documentation)