Asset

View as Markdown

Asset

An asset is one file uploaded to a stack, such as an image, a video or a PDF. Use the Asset class to

  • fetch one published asset by its UID
  • set the locale and response options for that fetch
  • read the file details, such as Url, FileName and FileSize, from the result

To list or filter many assets, use the AssetLibrary class instead.

client.Asset(Uid) creates the object and sends no request. It takes the one parameter below:

NameTypeDescription
UidstringUID of the asset to fetch.
NameTypeDescription
Uid string

UID of the asset. On a request object, the UID you passed.

Url string

Absolute URL of the file (url).

FileName string

Original name of the file (filename).

FileSize string

Size of the file in bytes, as text (file_size).

ContentType string

MIME type of the file (content_type), for example image/png.

Title string

Title of the asset in the requested locale (title).

Description string

Description of the asset (description).

Tags object[]

Tags on the asset (tags). Each item is a JsonElement.

Dimension Dictionary<string, object>

Image height and width (dimension). Each value is a JsonElement.

PublishDetails Dictionary<string, object>

Publish environment, locale and time (publish_details). Each value is a JsonElement.

Version int

Version number of the asset (_version).

IsDir bool

Whether the item is a folder (is_dir).

ParentUid string

UID of the folder that holds the asset (parent_uid).

CreatedBy string

UID of the user who created the asset (created_by).

UpdatedBy string

UID of the user who last updated the asset (updated_by).

ContentTypeUid string

Content type UID that the response gives the asset (_content_type_uid).

StackInstance ContentstackClient

Client that sends Fetch. null on an asset that Fetch returned.

this[string key] object

Any response field by its key, for example asset["filename"]. Returns null for a missing key.

AddParam

AddParam adds any query parameter to the Fetch request, for API options that have no method of their own.

NameTypeDescription
key (required)string

Name of the query parameter, for example include_dimension.

Default: Not applicable
value (required)string

Value of the query parameter, sent as written.

Default: Not applicable

Returns: Asset. The same asset, for chaining.

Validation

  • There is no client-side validation of the parameter name or value.
  • A null key throws ArgumentNullException.
  • A key that this object already holds throws ArgumentException. This includes a key that another method on this class sets, such as include_fallback after the IncludeFallback method.
  • environment passes AddParam, but the Fetch method then throws ArgumentException, because Fetch adds that parameter itself.
  • A null value sends the parameter with an empty value.
  • An invalid parameter surfaces as an AssetException when Fetch sends the request.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Client-side only. AddParam stores the pair and makes no request. Fetch sends it as key=value.
  • The SDK does not URL-encode the value. Encode a value that contains &, #, + or % yourself, for example with Uri.EscapeDataString.
  • For example, the API returns the height and width of an image with include_dimension set to true (Get a single asset). The SDK reads them into the Dimension property.

Example

Basic usage: include the image dimensions

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>")
        .AddParam("include_dimension", "true")
        .Fetch();

    if (asset.Dimension != null)
    {
        Console.WriteLine($"{asset.Dimension["width"]} x {asset.Dimension["height"]}");
    }
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

AssetFields

AssetFields requests additional field groups for the asset, such as its visual markups.

NameTypeDescription
fields (required)string[]

Field group names, for example visual_markups. Adds each group to the response.

Default: Not applicable

Returns: Asset. The same asset, for chaining.

Validation

  • There is no client-side validation of the field group names.
  • A call with no arguments, null or an empty array changes nothing.
  • A second call with at least one field group throws ArgumentException, because the SDK stores the asset_fields[] parameter once. Pass every group in one call.
  • An invalid group name surfaces as an AssetException when Fetch sends the request.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Client-side only. AssetFields adds one asset_fields[] query parameter per group and makes no request.
  • With visual_markups, the API returns the hotspot and bounding-box annotations of the asset under the visual_markups key. An asset with no markups returns an empty array (Get a single asset).
  • The SDK code comments also name user_defined_fields, embedded_metadata and ai_generated_metadata as accepted values.
  • Asset has no property for these groups. Read each one with the Get method under the key of the same name.

Example

Basic usage: request the visual markups of an asset

using System;
using System.Collections.Generic;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").AssetFields("visual_markups").Fetch();

    if (asset.Get("visual_markups") is List<object> markups)
    {
        Console.WriteLine($"{markups.Count} visual markups");
    }
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

All parameters: request several field groups in one call

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    // A second AssetFields call on the same object throws, so pass every group here.
    Asset asset = await client.Asset("<ASSET_UID>")
        .AssetFields("visual_markups", "user_defined_fields")
        .Fetch();

    Console.WriteLine(asset.Get("user_defined_fields"));
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

Fetch

Fetch retrieves one published asset by the UID you passed to client.Asset.

Returns: Task<Asset>. The requested asset.

Validation

  • There is no client-side validation of the UID. With a null or empty UID, Fetch requests /assets/ with no UID and throws AssetException.
  • Fetch throws AssetException when the API rejects the request. StatusCode, ErrorCode, Message and Errors carry the details from the error response. For example, an asset UID that does not exist returns status 404 with error code 145.
  • Fetch also throws AssetException when it cannot read the response, with the original error as InnerException.
  • Fetch throws ArgumentException before it sends anything when you passed environment to the AddParam method, because Fetch adds that parameter itself.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Fetch sends one GET /assets/{asset_uid} request (Get a single asset). It adds the client's environment, then every option you chained, as query parameters.
  • The request carries the client-level headers, the headers from SetHeader, and the branch header when the client sets Branch.
  • Fetch returns a new Asset built from the asset object in the response. The object you called Fetch on does not change and keeps its options.
  • The returned asset holds no client. Call Fetch on the object from client.Asset("<ASSET_UID>"), not on the result.
  • The API returns the latest published version of the asset in the client's environment.

Example

Basic usage: fetch an asset by UID

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();
    Console.WriteLine($"{asset.FileName}: {asset.Url}");
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

Fetch with every response option

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>")
        .SetLocale("<LOCALE>")
        .IncludeFallback()
        .IncludeMetadata()
        .IncludeBranch()
        .AssetFields("visual_markups")
        .Fetch();

    Console.WriteLine($"{asset.Title} (version {asset.Version})");
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

Edge case: resize an image through its URL

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    // The SDK has no image transformation methods. Add Image Delivery API
    // parameters to the URL yourself.
    string thumbnailUrl = $"{asset.Url}?width=300&format=webp";
    Console.WriteLine(thumbnailUrl);
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

Get

Get reads any field of the fetched asset by its key, including fields that have no property on Asset.

NameTypeDescription
key (required)string

Response field key, for example filename. Selects the value to return.

Default: Not applicable

Returns: object. The value stored under the key.

Validation

  • There is no client-side validation.
  • A key that the response does not contain returns null. A null key also returns null.

Behavior

  • Client-side only. Get reads the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, Get returns null for every key.
  • The list below maps each JSON value to the .NET type that Get returns:
    • text returns string
    • a whole number returns int, or long when it does not fit, and other numbers return double
    • true and false return bool
    • an object returns Dictionary<string, object>
    • an array returns List<object>
    • null returns null
  • The indexer asset["<key>"] returns the same value.

Example

Basic usage: read fields that have no property

using System;
using System.Collections.Generic;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    Console.WriteLine(asset.Get("filename"));

    if (asset.Get("publish_details") is Dictionary<string, object> publishDetails)
    {
        foreach (KeyValuePair<string, object> detail in publishDetails)
        {
            Console.WriteLine($"{detail.Key}: {detail.Value}");
        }
    }

    // A key the response does not contain returns null.
    Console.WriteLine(asset.Get("no_such_field") == null);
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

GetCreateAt

GetCreateAt reads the creation time of the fetched asset.

Returns: DateTime. The asset's creation time.

Validation

  • There is no client-side validation, and GetCreateAt does not throw.
  • When the response has no created_at field, or its value is not a date, GetCreateAt returns DateTime.MinValue.

Behavior

  • Client-side only. GetCreateAt reads the created_at field from the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, GetCreateAt returns DateTime.MinValue.
  • DateTime.Parse reads the value, so a UTC timestamp converts to the local time zone of the machine. Call ToUniversalTime() on the result to get UTC.

Example

Basic usage: read the created_at time of an asset

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    DateTime value = asset.GetCreateAt();
    if (value == DateTime.MinValue)
    {
        Console.WriteLine("The response has no created_at value.");
    }
    else
    {
        Console.WriteLine($"Created: {value.ToUniversalTime():u}");
    }
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

GetCreatedBy

GetCreatedBy reads the UID of the user who created the asset from the fetched asset.

Returns: string. The UID of the user who created the asset.

Validation

  • There is no client-side validation.
  • GetCreatedBy throws KeyNotFoundException when the response has no created_by field, because it reads the key without checking for it first.
  • GetCreatedBy throws NullReferenceException when the created_by value is null.

Behavior

  • Client-side only. GetCreatedBy reads the created_by field from the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, GetCreatedBy throws KeyNotFoundException.
  • The CreatedBy property holds the same value and returns null instead of throwing when the field is missing.

Example

Basic usage: read the created_by user of an asset

using System;
using System.Collections.Generic;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();
    Console.WriteLine(asset.GetCreatedBy());
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}
catch (KeyNotFoundException)
{
    // Thrown when the response has no created_by field
    Console.WriteLine("The response has no created_by value.");
}

Edge case: read the value without risking an exception

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    // Returns null when the field is missing, where GetCreatedBy throws.
    object user = asset.CreatedBy;
    Console.WriteLine(user ?? "not set");
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

GetDeleteAt

GetDeleteAt reads the deleted_at time from the fetched asset.

Returns: DateTime. The asset's deletion time.

Validation

  • There is no client-side validation, and GetDeleteAt does not throw.
  • When the response has no deleted_at field, or its value is not a date, GetDeleteAt returns DateTime.MinValue.

Behavior

  • Client-side only. GetDeleteAt reads the deleted_at field from the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, GetDeleteAt returns DateTime.MinValue.
  • DateTime.Parse reads the value, so a UTC timestamp converts to the local time zone of the machine. Call ToUniversalTime() on the result to get UTC.
  • Compare the result with DateTime.MinValue to tell whether the response carried a deleted_at value.

Example

Basic usage: read the deleted_at time of an asset

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    DateTime value = asset.GetDeleteAt();
    if (value == DateTime.MinValue)
    {
        Console.WriteLine("The response has no deleted_at value.");
    }
    else
    {
        Console.WriteLine($"Deleted: {value.ToUniversalTime():u}");
    }
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

GetDeletedBy

GetDeletedBy reads the deleted_by user UID from the fetched asset.

Returns: string. The UID of the user who deleted the asset.

Validation

  • There is no client-side validation.
  • GetDeletedBy throws KeyNotFoundException when the response has no deleted_by field, because it reads the key without checking for it first.
  • GetDeletedBy throws NullReferenceException when the deleted_by value is null.

Behavior

  • Client-side only. GetDeletedBy reads the deleted_by field from the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, GetDeletedBy throws KeyNotFoundException.
  • Asset has no property for deleted_by. The Get method returns null instead of throwing when the field is missing.

Example

Basic usage: read the deleted_by user of an asset

using System;
using System.Collections.Generic;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();
    Console.WriteLine(asset.GetDeletedBy());
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}
catch (KeyNotFoundException)
{
    // Thrown when the response has no deleted_by field
    Console.WriteLine("The response has no deleted_by value.");
}

Edge case: read the value without risking an exception

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    // Returns null when the field is missing, where GetDeletedBy throws.
    object user = asset.Get("deleted_by");
    Console.WriteLine(user ?? "not set");
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

GetUpdateAt

GetUpdateAt reads the last update time of the fetched asset.

Returns: DateTime. The asset's last update time.

Validation

  • There is no client-side validation, and GetUpdateAt does not throw.
  • When the response has no updated_at field, or its value is not a date, GetUpdateAt returns DateTime.MinValue.

Behavior

  • Client-side only. GetUpdateAt reads the updated_at field from the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, GetUpdateAt returns DateTime.MinValue.
  • DateTime.Parse reads the value, so a UTC timestamp converts to the local time zone of the machine. Call ToUniversalTime() on the result to get UTC.

Example

Basic usage: read the updated_at time of an asset

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    DateTime value = asset.GetUpdateAt();
    if (value == DateTime.MinValue)
    {
        Console.WriteLine("The response has no updated_at value.");
    }
    else
    {
        Console.WriteLine($"Last updated: {value.ToUniversalTime():u}");
    }
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

GetUpdatedBy

GetUpdatedBy reads the UID of the user who last updated the asset from the fetched asset.

Returns: string. The UID of the user who last updated the asset.

Validation

  • There is no client-side validation.
  • GetUpdatedBy throws KeyNotFoundException when the response has no updated_by field, because it reads the key without checking for it first.
  • GetUpdatedBy throws NullReferenceException when the updated_by value is null.

Behavior

  • Client-side only. GetUpdatedBy reads the updated_by field from the response that Fetch or FetchAll stored and makes no request.
  • On the object from client.Asset("<ASSET_UID>"), which holds no response, GetUpdatedBy throws KeyNotFoundException.
  • The UpdatedBy property holds the same value and returns null instead of throwing when the field is missing.

Example

Basic usage: read the updated_by user of an asset

using System;
using System.Collections.Generic;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();
    Console.WriteLine(asset.GetUpdatedBy());
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}
catch (KeyNotFoundException)
{
    // Thrown when the response has no updated_by field
    Console.WriteLine("The response has no updated_by value.");
}

Edge case: read the value without risking an exception

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").Fetch();

    // Returns null when the field is missing, where GetUpdatedBy throws.
    object user = asset.UpdatedBy;
    Console.WriteLine(user ?? "not set");
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

IncludeBranch

IncludeBranch adds the _branch key, which names the branch the asset belongs to, to the Fetch response.

Returns: Asset. The same asset, for chaining.

Validation

  • There is no client-side validation.
  • A second call on the same object throws ArgumentException, because the SDK stores each query parameter once.
  • An invalid request surfaces as an AssetException when Fetch sends it.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Client-side only. IncludeBranch adds include_branch=true to the request and makes no request itself.
  • The API adds the _branch key with the unique ID of the branch (Get a single asset). Asset has no property for it. Read it with the Get method.
  • IncludeBranch does not choose the branch. The Branch option of the client sends the branch header that selects it.

Example

Basic usage: read the branch of an asset

using System;
using Contentstack.Core;
using Contentstack.Core.Configuration;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient(new ContentstackOptions
{
    ApiKey = "<API_KEY>",
    DeliveryToken = "<DELIVERY_TOKEN>",
    Environment = "<ENVIRONMENT>",
    Branch = "<BRANCH>"
});

try
{
    Asset asset = await client.Asset("<ASSET_UID>").IncludeBranch().Fetch();
    Console.WriteLine(asset.Get("_branch"));
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

IncludeFallback

IncludeFallback returns the asset from the fallback locale when the requested locale has no published version.

Returns: Asset. The same asset, for chaining.

Validation

  • There is no client-side validation.
  • A second call on the same object throws ArgumentException, because the SDK stores each query parameter once.
  • An invalid request surfaces as an AssetException when Fetch sends it.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Client-side only. IncludeFallback adds include_fallback=true to the request and makes no request itself.
  • The API returns the published asset details from the fallback locale when the specified locale does not contain published content (Get a single asset).
  • Pair it with the SetLocale method, which names the locale that the fallback starts from.

Example

Basic usage: fetch an asset with locale fallback

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>")
        .SetLocale("<LOCALE>")
        .IncludeFallback()
        .Fetch();

    Console.WriteLine(asset.Title);
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

IncludeMetadata

IncludeMetadata adds the asset metadata, which extensions store on the asset, to the Fetch response.

Returns: Asset. The same asset, for chaining.

Validation

  • There is no client-side validation.
  • A second call on the same object throws AssetException, because the SDK stores each query parameter once. The original ArgumentException is the InnerException.
  • An invalid request surfaces as an AssetException when Fetch sends it.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Client-side only. IncludeMetadata adds include_metadata=true to the request and makes no request itself.
  • The API returns the metadata under the _metadata key of the asset (Get a single asset).
  • Asset has no property for _metadata. Read it with the Get method, which returns it as a Dictionary<string, object>.

Example

Basic usage: read the asset metadata

using System;
using System.Collections.Generic;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").IncludeMetadata().Fetch();

    // Metadata is keyed by the UID of the extension that added it.
    if (asset.Get("_metadata") is Dictionary<string, object> metadata)
    {
        foreach (KeyValuePair<string, object> item in metadata)
        {
            Console.WriteLine(item.Key);
        }
    }
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

RemoveHeader

RemoveHeader removes a header that the SetHeader method added to this asset object.

NameTypeDescription
key (required)string

Header name. Identifies the header to remove.

Default: Not applicable

Returns: void. This method returns nothing.

Validation

  • There is no client-side validation.
  • A null key throws ArgumentNullException.
  • A key that this object does not hold changes nothing.

Behavior

  • Client-side only. RemoveHeader deletes the header from this asset object and makes no request.
  • It does not remove a client-level header, such as api_key or access_token. When SetHeader overrode a client-level header, removing it makes Fetch send the client value again.
  • RemoveHeader returns nothing, so you cannot chain after it. Call it as a separate statement.

Example

Basic usage: remove a header before the request

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

Asset request = client.Asset("<ASSET_UID>");
request.SetHeader("x-request-id", "asset-sync-42");
request.RemoveHeader("x-request-id");

try
{
    // Fetch sends only the client-level headers.
    Asset asset = await request.Fetch();
    Console.WriteLine(asset.Url);
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

SetHeader

SetHeader adds an HTTP header to the Fetch request of this asset object only.

NameTypeDescription
key (required)string

Header name. Identifies the header to send.

Default: Not applicable
value (required)string

Header value. Sent with the header name.

Default: Not applicable

Returns: void. This method returns nothing.

Validation

  • There is no client-side validation of the name or value.
  • A null key or a null value changes nothing. SetHeader ignores the call.
  • A header name that HTTP does not allow, such as an empty string, passes SetHeader. Fetch then drops the header without an error.

Behavior

  • Client-side only. SetHeader stores the header and makes no request.
  • A second call with the same key replaces the value.
  • Fetch sends these headers together with the client-level headers. When both name the same header, the value from SetHeader wins. Use this to send a different delivery token (access_token) for one asset.
  • The header applies to this asset object only. Other assets and entries from the same client do not get it.
  • SetHeader returns nothing, so you cannot chain after it. Call it as a separate statement.

Example

Basic usage: add a custom header to one request

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

Asset request = client.Asset("<ASSET_UID>");
request.SetHeader("x-request-id", "asset-sync-42");

try
{
    Asset asset = await request.Fetch();
    Console.WriteLine(asset.Url);
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

Edge case: override the client's delivery token for one asset

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

Asset request = client.Asset("<ASSET_UID>");

// This value replaces the client-level access_token header for this request only.
request.SetHeader("access_token", "<DELIVERY_TOKEN>");

try
{
    Asset asset = await request.Fetch();
    Console.WriteLine(asset.FileName);
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}

SetLocale

SetLocale sets the locale that Fetch requests the asset in.

NameTypeDescription
locale (required)string

Locale code, for example en-us. Selects the asset localization.

Default: Not applicable

Returns: Asset. The same asset, for chaining.

Validation

  • There is no client-side validation of the locale code.
  • A null or empty locale changes nothing. SetLocale ignores it and keeps any locale set before.
  • An invalid value surfaces as an AssetException when Fetch sends the request.

Additional Resource Refer to Content Delivery API Errors for the full error code list.

Behavior

  • Client-side only. SetLocale stores the locale query parameter and makes no request.
  • A second call replaces the locale. Unlike the other options on this class, it does not throw.
  • The localized title arrives in the Title property of the asset that Fetch returns.
  • Chain the IncludeFallback method to get the fallback locale version when the asset has no published localization in locale (Get a single asset).

Example

Basic usage: fetch an asset in a locale

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>").SetLocale("<LOCALE>").Fetch();
    Console.WriteLine(asset.Title);
}
catch (ContentstackException e)
{
    // Thrown when the API rejects the request
    Console.WriteLine($"Request failed: {(int)e.StatusCode} {e.ErrorCode} {e.Message}");
}

Edge case: fall back when the locale has no published version

using System;
using Contentstack.Core;
using Contentstack.Core.Internals;
using Contentstack.Core.Models;

ContentstackClient client = new ContentstackClient("<API_KEY>", "<DELIVERY_TOKEN>", "<ENVIRONMENT>");

try
{
    Asset asset = await client.Asset("<ASSET_UID>")
        .SetLocale("<LOCALE>")
        .IncludeFallback()
        .Fetch();

    // With IncludeFallback, the title can come from the fallback locale.
    Console.WriteLine(asset.Title);
}
catch (ContentstackException e)
{
    Console.WriteLine(e.Message);
}