Metadata allows users and applications to define and store custom data associated
with their files/folders. Metadata consists of key:value pairs that belong to
files/folders. For example, an important contract may have key:value pairs of
"clientNumber":"820183"
and "clientName":"bioMedicalCorp"
.
Metadata that belongs to a file/folder is grouped by templates. Templates allow the metadata service to provide a multitude of services, such as pre-defining sets of key:value pairs or schema enforcement on specific fields.
Each file/folder can have multiple distinct template instances associated with it,
and templates are also grouped by scopes. Currently, the only scopes support are
enterprise
and global
. Enterprise scopes are defined on a per enterprises basis,
whereas global scopes are Box application-wide.
In addition to enterprise
scoped templates, every file on Box has access to the
global
properties
template. The Properties template is a bucket of free form
key:value string pairs, with no additional schema associated with it. Properties
are ideal for scenarios where applications want to write metadata to file objects
in a flexible way, without pre-defined template structure.
- Create Metadata Template
- Update Metadata Template
- Get Metadata Template
- Get Enterprise Metadata Templates
- Set Metadata on a File
- Get Metadata on a File
- Remove Metadata from a File
- Set Metadata on a Folder
- Get Metadata on a Folder
- Remove Metadata from a Folder
- Execute Metadata Query
To create a new metadata template, call
MetadataManager.CreateMetadataTemplate(BoxMetadataTemplate template)
.
var templateParams = new BoxMetadataTemplate()
{
TemplateKey = "marketingCollateral",
DisplayName = "Marketing Collateral",
Scope = "enterprise",
Fields = new List<BoxMetadataTemplateField>()
{
new BoxMetadataTemplateField()
{
Type = "enum",
Key = "audience",
DisplayName = "Audience",
Options = new List<BoxMetadataTemplateFieldOption>()
{
new BoxMetadataTemplateFieldOption() { Key = "internal" },
new BoxMetadataTemplateFieldOption() { Key = "external" }
}
},
new BoxMetadataTemplateField()
{
Type = "string",
Key = "author",
DisplayName = "Author"
}
}
};
BoxMetadataTemplate template = await client.MetadataManager.CreateMetadataTemplate(templateParams);
To update a metadata template, call the
MetadataManager.UpdateMetadataTemplate(IEnumerable<BoxMetadataTemplateUpdate> metadataTemplateUpdate, string scope, string template)
method with the operations to perform on the template. See the
API Documentation
for more information on the operations available.
var updates = new List<BoxMetadataTemplateUpdate>()
{
new BoxMetadataTemplateUpdate()
{
Op = MetadataTemplateUpdateOp.addEnumOption,
FieldKey = "fy",
Data = new {
key = "FY20"
}
},
new BoxMetadataTemplateUpdate()
{
Op = MetadataTemplateUpdateOp.editTemplate,
Data = new {
hidden = false
}
}
};
BoxMetadataTemplate updatedTemplate = await client.MetadataManager
.UpdateMetadataTemplate(updates, "enterprise", "marketingCollateral");
To retrieve a specific metadata template by its scope and template key, call the
MetadataManager.GetMetadataTemplate(string scope, string template)
method with the scope and template key.
BoxMetadataTemplate template = await client.MetadataManager
.GetMetadataTemplate("enterprise", "marketingCollateral");
To get a specific metadata template by its ID, call the
MetadataManager.GetMetadataTemplateById(string templateId)
method with the ID of the template.
BoxMetadataTemplate template = await client.MetadataManager
.GetMetadataTemplateById("17f2d715-6acb-45f2-b96a-28b15efc9faa");
Get all metadata templates for the current enterprise and scope by calling
MetadataManager.GetEnterpriseMetadataAsync(string scope = "enterprise")
.
BoxEnterpriseMetadataTemplateCollection<BoxMetadataTemplate> templates = await client.MetadataManager
.GetEnterpriseMetadataAsync();
Get all metadata templates available to all enterprises by calling
MetadataManager.GetEnterpriseMetadataAsync(string scope = "global")
.
BoxEnterpriseMetadataTemplateCollection<BoxMetadataTemplate> templates = await client.MetadataManager
.GetEnterpriseMetadataAsync("global");
To set metadata on a file, call
MetadataManager.SetFileMetadataAsync(string fileId, Dictionary<string, object> metadata, string scope, string template)
with the scope and template key of the metadata template, as well as a Dictionary
containing the metadata keys
and values to set.
Note: This method will unconditionally apply the provided metadata, overwriting existing metadata for the keys provided. To specifically create or update metadata, see the
CreateFileMetadataAsync()
andUpdateFileMetadataAsync()
methods below.
var metadataValues = new Dictionary<string, object>()
{
{ "audience", "internal" },
{ "documentType", "Q1 plans" },
{ "competitiveDocument", "no" },
{ "status", "active" },
{ "author": "M. Jones" },
{ "currentState": "proposal" }
};
Dictionary<string, object> metadata = await client.MetadataManager
.SetFileMetadataAsync(fileId: "11111", metadataValues, "enterprise", "marketingCollateral");
To add new metadata to a file, call
MetadataManager.CreateFileMetadataAsync(string fileId, Dictionary<string, object> metadata, string scope, string template)
with a metadata template and a Dictionary
of key/value pairs to add as metadata.
Note:: This method will only succeed if the provided metadata template is not current applied to the file, otherwise it will fail with a Conflict error.
var metadataValues = new Dictionary<string, object>()
{
{ "audience", "internal" },
{ "documentType", "Q1 plans" },
{ "competitiveDocument", "no" },
{ "status", "active" },
{ "author": "M. Jones" },
{ "currentState": "proposal" }
};
Dictionary<string, object> metadata = await client.MetadataManager
.CreateFileMetadataAsync(fileId: "11111", metadataValues, "enterprise", "marketingCollateral");
Update a file's existing metadata by calling
MetadataManager.UpdateFileMetadataAsync(string fileId, List<BoxMetadataUpdate> updates, string scope, string template)
with a list of update operations to apply.
Note: This method will only succeed if the provided metadata template has already been applied to the file; if the file does not have existing metadata, this method will fail with a Not Found error. This is useful in cases where you know the file will already have metadata applied, since it will save an API call compared to
SetFileMetadataAsync()
.
var updates = new List<BoxMetadataUpdate>()
{
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/competitiveDocument",
Value = "no"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.remove,
Path = "/competitiveDocument"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/status",
Value = "active"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.replace,
Path = "/competitiveDocument",
Value = "inactive"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/author",
Value = "Jones"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.copy,
From="/author",
Path = "/editor"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/currentState",
Value = "proposal"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.move,
From = "/currentState",
Path = "/previousState"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.add,
Path = "/currentState",
Value = "reviewed"
}
};
Dictionary<string, object> updatedMetadata = await client.MetadataManager
.UpdateFileMetadataAsync("11111", updates, "enterprise", "marketingCollateral");
Retrieve a specific metadata template on a file by calling
MetadataManager.GetFileMetadataAsync(string fileId, string scope, string template)
with the ID of the file and which template to fetch.
Dictionary<string, object> metadata = await client.MetadataManager.
.GetFileMetadataAsync(fileId: "11111", "enterprise", "marketingCollateral");
You can also get all metadata on a file by calling MetadataManager.GetAllFileMetadataTemplatesAsync(string fileId)
.
BoxMetadataTemplateCollection<Dictionary<string, object>> metadataInstances = await client.MetadataManager
.GetAllFileMetadataTemplatesAsync(fileId: "11111");
A metadata template can be removed from a file by calling
MetadataManager.DeleteFileMetadataAsync(string fileId, string scope, string template)
with the ID of the file and the metadata template to remove.
await client.MetadataManager.DeleteFileMetadataAsync("11111", "enterprise", "marketingCollateral");
To set metadata on a folder, call
MetadataManager.SetFolderMetadataAsync(string folderId, Dictionary<string, object> metadata, string scope, string template)
with the scope and template key of the metadata template, as well as a Dictionary
containing the metadata keys
and values to set.
Note: This method will unconditionally apply the provided metadata, overwriting existing metadata for the keys provided. To specifically create or update metadata, see the
CreateFileMetadataAsync()
andUpdateFileMetadataAsync()
methods below.
var metadataValues = new Dictionary<string, object>()
{
{ "audience", "internal" },
{ "documentType", "Q1 plans" },
{ "competitiveDocument", "no" },
{ "status", "active" },
{ "author": "M. Jones" },
{ "currentState": "proposal" }
};
Dictionary<string, object> metadata = await client.MetadataManager
.SetFolderMetadataAsync(folderId: "11111", metadataValues, "enterprise", "marketingCollateral");
To add new metadata to a folder, call
MetadataManager.CreateFolderMetadataAsync(string folderId, Dictionary<string, object> metadata, string scope, string template)
with a metadata template and a Dictionary
of key/value pairs to add as metadata.
Note:: This method will only succeed if the provided metadata template is not current applied to the folder, otherwise it will fail with a Conflict error.
var metadataValues = new Dictionary<string, object>()
{
{ "audience", "internal" },
{ "documentType", "Q1 plans" },
{ "competitiveDocument", "no" },
{ "status", "active" },
{ "author": "M. Jones" },
{ "currentState": "proposal" }
};
Dictionary<string, object> metadata = await client.MetadataManager
.CreateFolderMetadataAsync(folderId: "11111", metadataValues, "enterprise", "marketingCollateral");
Update a folder's existing metadata by calling
MetadataManager.UpdateFolderMetadataAsync(string folderId, List<BoxMetadataUpdate> updates, string scope, string template)
with a list of update operations to apply.
Note: This method will only succeed if the provided metadata template has already been applied to the folder; if the folder does not have existing metadata, this method will fail with a Not Found error. This is useful in cases where you know the folder will already have metadata applied, since it will save an API call compared to
SetFolderMetadataAsync()
.
var updates = new List<BoxMetadataUpdate>()
{
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/competitiveDocument",
Value = "no"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.remove,
Path = "/competitiveDocument"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/status",
Value = "active"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.replace,
Path = "/competitiveDocument",
Value = "inactive"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/author",
Value = "Jones"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.copy,
From="/author",
Path = "/editor"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.test,
Path = "/currentState",
Value = "proposal"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.move,
From = "/currentState",
Path = "/previousState"
},
new BoxMetadataUpdate()
{
Op = MetadataUpdateOp.add,
Path = "/currentState",
Value = "reviewed"
}
};
Dictionary<string, object> updatedMetadata = await client.MetadataManager
.UpdateFolderMetadataAsync("11111", updates, "enterprise", "marketingCollateral");
Retrieve a specific metadata template on a folder by calling
MetadataManager.GetFolderMetadataAsync(string folderId, string scope, string template)
with the ID of the folder and which template to fetch.
Dictionary<string, object> metadata = await client.MetadataManager.
.GetFolderMetadataAsync(folderId: "11111", "enterprise", "marketingCollateral");
You can also get all metadata on a folder by calling
MetadataManager.GetAllFolderMetadataTemplatesAsync(string folderId)
.
BoxMetadataTemplateCollection<Dictionary<string, object>> metadataInstances = await client.MetadataManager
.GetAllFolderMetadataTemplatesAsync(folderId: "11111");
A metadata template can be removed from a folder by calling
MetadataManager.DeleteFolderMetadataAsync(string folderId, string scope, string template)
with the ID of the folder and the metadata template to remove.
await client.MetadataManager.DeleteFolderMetadataAsync("11111", "enterprise", "marketingCollateral");
There are two types of methods for executing a metadata query, methods without the fields parameter and with it. The method with the fields parameters returns a BoxItem
object. The method without the fields parameters returns data that is a BoxMetadataQueryItem
and is deprecated. The API will eventually not support this method and the other method should be used instead. Examples of these two types are shown below.
The MetadataManager.ExecuteMetadataQueryAsync(string from, string ancestorFolderId, IEnumerable<string> fields, string query, Dictionary<string, object> queryParameters, string indexName, List<BoxMetadataQueryOrderBy> orderBy, int limit, string marker, bool autoPaginate)
method queries files and folders based on their metadata and allows for fields to be passed in. A returned BoxItem
must be cast to a BoxFile
or BoxFolder
to get its metadata.
var queryParams = new Dictionary<string, object>();
queryParams.Add("arg", "Bob Dylan");
List<string> fields = new List<string>();
fields.Add("id");
fields.Add("name");
fields.Add("sha1");
fields.Add("metadata.enterprise_240748.catalogImages.photographer");
BoxCollectionMarkerBased<BoxItem> items = await _metadataManager.ExecuteMetadataQueryAsync(from: "enterprise_67890.catalogImages", query: "photographer = :arg", fields: fields, queryParameters: queryParams, ancestorFolderId: "0", autoPaginate: true);
BoxFile file = (BoxFile) items.Entries[0];
BoxFolder folder = (BoxFolder) items.Entries[1];
string metadataFile = file.Metadata["enterprise_240748"]["catalogImages"]["photographer"].Value;
string metadataFolder = folder.Metadata["enterprise_240748"]["catalogImages"]["photographer"].Value;
Deprecated
The MetadataManager.ExecuteMetadataQueryAsync(string from, string ancestorFolderId, string query = null, Dictionary<string, object> queryParameters, string indexName, List<BoxMetadataQueryOrderBy> orderBy, int limit, string marker, bool autoPaginate)
method queries files and folders based on their metadata.
var queryParams = new Dictionary<string, object>();
queryParams.Add("arg", 100);
List<BoxMetadataQueryOrderBy> orderByList = new List<BoxMetadataQueryOrderBy>();
var orderBy = new BoxMetadataQueryOrderBy()
{
FieldKey = "amount",
Direction = BoxSortDirection.ASC
};
orderByList.Add(orderBy);
BoxCollectionMarkerBased<BoxMetadataQueryItem> items = await _metadataManager.ExecuteMetadataQueryAsync(from: "enterprise_123456.someTemplate", query: "amount >= :arg", queryParameters: queryParams, ancestorFolderId: "5555", indexName: "amountAsc", orderBy: orderByList, autoPaginate: true);