Web script example

This is an example of an Action script that reads the aggregated data of an asset, it's related asset type and it's related tags. The script is designed to be executed using the Web API.

Use case

Asset metadata can be stored both in 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 do multiple round trips to the web-server.

Script

RequestResponse

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

  1. Include the libraries to be used in the script.

    RequestResponse
    
    using System.Linq;
    using System.Net;
    using Newtonsoft.Json.Linq;
    using System.Globalization;
    
    
  2. 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 in en-US will be loaded.

    RequestResponse
    
    var enUsCulture = CultureInfo.GetCultureInfo("en-US");
    
    
  3. Data from the request is specified in Context.Data, which is a JToken. The script expects it to be a JObject containing an assetId property. The property contains the ID of the asset to get the data for. If the asset-id could not be extracted from the data, return http status-code 400 (bad request) together with a user-friendly error-message.

    RequestResponse
    
    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; 
    }
    
    
  4. Load the asset with the specified ID. Only the Title and FileName properties, and, the TagToAsset and AssetTypeToAsset relations are of interest. If the asset could not be found, return http status-code 404 (not found) together with a user-friendly error-message.

    RequestResponse
    
    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;
    }
    
    
  5. Create a new JObject which will eventually be returned as a result of the script. Immediately add the values of properties Title and FileName.

    RequestResponse
    
    var result = new JObject(
      new JProperty("title", asset.GetPropertyValue<string>("Title")),
      new JProperty("filename", asset.GetPropertyValue<string>("FileName"))
    );
    
    
  6. Load the tags associated with the asset. Immediately extract the TagName property from the tags and put them in a JArray, which in turn, is added to the result.

    RequestResponse
    
    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);
      }
    }
    
    
  7. Load the asset-type associated with the asset. Immediately extract the Label property from the asset-type and put it's value in the result.

    Note

    Label is a multi-language property. Hence, specify the en-US culture to get it's value in the English language.

    RequestResponse
    
    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);
      }
    }
    
    
  8. Store the result object on the Context. This tells the script to return it to the user.

    RequestResponse
    
    Context.Result = result;
    
    
  9. SetError is a helper function which is used to return errors from the script. It stores the specified http status-code and error-message on the Context. This tells the script to return it to the user.

    RequestResponse
    
    void SetError(HttpStatusCode statusCode, string message)
    {
      Context.StatusCode = statusCode;
      Context.Result = new JObject(new JProperty("error", message));
    }
    
    

Setup

  1. Create, publish and enable an Action script.

  2. Execute an HTTP POST call 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 the Content-Type header is set to application/json. Use the following template as body for the script:

    RequestResponse
    
    {
     "assetId": my-asset-id
    }
    
    

Do you have some feedback for us?

If you have suggestions for improving this article,