Read asset metadata
This is an example of an Action web script that reads the aggregated data of an asset, its related asset type, and its related tags. The script is designed to be executed using the Web API.
Asset metadata can be stored in both properties and relations. The relations link associated tags and asset-types to the asset. These related entities also have metadata of their own. The script allows users to retrieve all of this data in a single Web API call, eliminating the need to make repeated calls to the web server.
-
Verify the required API endpoints are active and accessible for the script's logic.
-
Ensure the schema includes properties and relations referenced in the script, such as asset metadata or identifiers.
Script
using System.Linq;
using System.Net;
using Newtonsoft.Json.Linq;
using System.Globalization;
var enUsCulture = CultureInfo.GetCultureInfo("en-US");
var data = Context.Data as JObject;
var assetId = data?["assetId"]?.Value<long>();
if (assetId == null)
{
SetError(HttpStatusCode.BadRequest, "No asset-id has been specified."); // Bad request
return;
}
var loadConfig = new EntityLoadConfiguration(
CultureLoadOption.Default,
new PropertyLoadOption("Title", "FileName"),
new RelationLoadOption("TagToAsset", "AssetTypeToAsset"));
var asset = await MClient.Entities.GetAsync(assetId.Value, loadConfig);
if (asset == null)
{
SetError(HttpStatusCode.NotFound, "Asset not found.");
return;
}
var result = new JObject(
new JProperty("title", asset.GetPropertyValue<string>("Title")),
new JProperty("filename", asset.GetPropertyValue<string>("FileName"))
);
var tagIds = asset.GetRelation<IChildToManyParentsRelation>("TagToAsset").Parents;
if (tagIds.Any())
{
var tags = await MClient.Entities.GetManyAsync(tagIds);
var tagNames = tags.Select(t => t.GetPropertyValue<string>("TagName"));
if (tagNames.Any())
{
result["tags"] = new JArray(tagNames);
}
}
var typeId = asset.GetRelation<IChildToOneParentRelation>("AssetTypeToAsset").Parent;
if (typeId.HasValue)
{
var type = await MClient.Entities.GetAsync(typeId.Value);
if (type != null)
{
result["type"] = type.GetPropertyValue<string>("Label", enUsCulture);
}
}
Context.Result = result;
void SetError(HttpStatusCode statusCode, string message)
{
Context.StatusCode = statusCode;
Context.Result = new JObject(new JProperty("error", message));
}
Script explanation
This section steps through the script in execution order, explaining each part. The numbered items describe the sequence, not instructions to perform.
-
Include the libraries to be used in the script.
RequestResponseusing System.Linq; using System.Net; using Newtonsoft.Json.Linq; using System.Globalization; -
Some of the properties are
multi-language. This means they can have different values in different languages. For the purpose of this example, only their values inen-USwill be loaded.RequestResponsevar enUsCulture = CultureInfo.GetCultureInfo("en-US"); -
Data from the request is specified in
Context.Data, which is aJToken. The script expects it to be aJObjectcontaining anasset Idproperty. The property contains the ID of the asset to get the data for. If theassetidcould not be extracted from the data, returnHTTP 400status code (bad request) together with a user-friendly error message.RequestResponsevar data = Context.Data as JObject; var assetId = data?["assetId"]?.Value<long>(); if (assetId == null) { SetError(HttpStatusCode.BadRequest, "No asset-id has been specified."); // Bad request return; } -
Load the asset with the specified ID. Only the
TitleandFileNameproperties, and, theTagToAssetandAssetTypeToAssetrelations are of interest. If the asset could not be found, return http status-code 404 (not found) together with a user-friendly error-message.RequestResponsevar loadConfig = new EntityLoadConfiguration( CultureLoadOption.Default, new PropertyLoadOption("Title", "FileName"), new RelationLoadOption("TagToAsset", "AssetTypeToAsset")); var asset = await MClient.Entities.GetAsync(assetId.Value, loadConfig); if (asset == null) { SetError(HttpStatusCode.NotFound, "Asset not found."); return; } -
The script then creates a new
JObjectthat will eventually be returned as a result of the script, and then adds the values of theTitleandFileNameproperties to the newJObject.RequestResponsevar result = new JObject( new JProperty("title", asset.GetPropertyValue<string>("Title")), new JProperty("filename", asset.GetPropertyValue<string>("FileName")) ); -
Load the tags associated with the asset. Immediately extract the
TagNameproperty from the tags and put them in aJArray, which in turn, is added to the result.RequestResponsevar tagIds = asset.GetRelation<IChildToManyParentsRelation>("TagToAsset").Parents; if (tagIds.Any()) { var tags = await MClient.Entities.GetManyAsync(tagIds); var tagNames = tags.Select(t => t.GetPropertyValue<string>("TagName")); if (tagNames.Any()) { result["tags"] = new JArray(tagNames); } } -
Load the asset type associated with the asset. Immediately extract the
Labelproperty from the asset type and put its value in the result.NoteLabelis a multi-language property, which means that you need to specifyen-USto get its value in English.RequestResponsevar typeId = asset.GetRelation<IChildToOneParentRelation>("AssetTypeToAsset").Parent; if (typeId.HasValue) { var type = await MClient.Entities.GetAsync(typeId.Value); if (type != null) { result["type"] = type.GetPropertyValue<string>("Label", enUsCulture); } } -
Store the result object on the
Context. This tells the script to return it to the user.RequestResponseContext.Result = result; -
SetErroris a helper function that is used to return errors from the script. It stores the specified HTTP status code and error message on theContext. This tells the script to return it to the user.RequestResponsevoid SetError(HttpStatusCode statusCode, string message) { Context.StatusCode = statusCode; Context.Result = new JObject(new JProperty("error", message)); }
Setup
-
Create a script of the Action type, publish it, and enable it.
-
Execute an HTTP
POSTcall to the following endpoint:https://<MY_URL>/api/scripts/<MY_SCRIPT_IDENTIFIER/execute. Make sure to replace MY_URL and MY_SCRIPT_IDENTIFIER with the correct values. Make sure theContent-Typeheader is set toapplication/json. Use the following template as body for the script:RequestResponse{ "assetId": <MY_ASSET_ID> }