Skip to content

Commit 84977ab

Browse files
committed
feat: add AssetFields() to support CDA asset_fields[] parameter
Add AssetFields(params string[] fields) across Entry, Query, Asset, and AssetLibrary to support the Content Delivery API (CDA) asset_fields[] query parameter. This enables requesting specific asset-related metadata (user_defined_fields, embedded, ai_suggested, visual_markups) when fetching entries or assets. Changes: - Entry: AssetFields() before Fetch (single entry). - Query: AssetFields() before Find (entries). - Asset: AssetFields() before Fetch (single asset). - AssetLibrary: AssetFields() before FetchAll (assets). Behavior: when called with one or more fields, sets asset_fields[] in the request; when called with no arguments, null, or empty array, the parameter is not set. Method returns this for chaining. Tests: - Unit tests (Contentstack.Core.Unit.Tests): 24 tests across Entry, Query, Asset, AssetLibrary (single/multiple fields, chaining, no-args/null/empty-array). - API tests (Contentstack.Core.Tests): AssetFields request success, chaining with IncludeMetadata, and scenarios mirroring unit tests (single field, no args, null, empty array) for Entry, Query, Asset, and AssetLibrary. Version: 2.26.0 (Directory.Build.props, CHANGELOG.md).
1 parent a9eaa96 commit 84977ab

16 files changed

Lines changed: 813 additions & 4 deletions

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
### Version: 2.26.0
2+
#### Date: Feb-10-2026
3+
4+
##### Feat:
5+
- CDA / DAM 2.0 – AssetFields support
6+
- Added `AssetFields(params string[] fields)` to request specific asset-related metadata via the CDA `asset_fields[]` query parameter
7+
- Implemented on: Entry (single entry fetch), Query (entries find), Asset (single asset fetch), AssetLibrary (assets find)
8+
- Supported asset field values: `user_defined_fields`, `embedded`, `ai_suggested`, `visual_markups`
9+
- Method is chainable; when called with no arguments, the query parameter is not set
10+
111
### Version: 2.25.2
212
#### Date: Nov-13-2025
313

Contentstack.Core.Tests/AssetTest.cs

Lines changed: 157 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using Xunit;
33
using Contentstack.Core.Models;
44
using System.Threading.Tasks;
@@ -951,5 +951,161 @@ public void Where_WithSpecialCharacters_ShouldHandleCorrectly_Test()
951951
Assert.NotNull(result);
952952
Assert.IsType<AssetLibrary>(result);
953953
}
954+
955+
[Fact]
956+
public async Task AssetFields_SingleAsset_RequestSucceeds()
957+
{
958+
string uid = await FetchAssetUID();
959+
Asset asset = client.Asset(uid);
960+
961+
asset.AssetFields("user_defined_fields", "embedded_metadata", "ai_generated_metadata", "visual_markups");
962+
Asset result = await asset.Fetch();
963+
964+
if (result == null)
965+
Assert.Fail("Asset.Fetch with AssetFields did not return a result.");
966+
Assert.NotNull(result.Uid);
967+
Assert.NotEmpty(result.FileName);
968+
}
969+
970+
[Fact]
971+
public async Task AssetFields_AssetLibrary_RequestSucceeds()
972+
{
973+
AssetLibrary assetLibrary = client.AssetLibrary();
974+
assetLibrary.AssetFields("user_defined_fields", "ai_generated_metadata");
975+
ContentstackCollection<Asset> assets = await assetLibrary.FetchAll();
976+
977+
if (assets == null)
978+
Assert.Fail("AssetLibrary.FetchAll with AssetFields did not return a result.");
979+
Assert.NotNull(assets.Items);
980+
}
981+
982+
[Fact]
983+
public async Task AssetFields_ChainedWithIncludeMetadata_RequestSucceeds()
984+
{
985+
string uid = await FetchAssetUID();
986+
Asset result = await client.Asset(uid)
987+
.AssetFields("user_defined_fields")
988+
.IncludeMetadata()
989+
.Fetch();
990+
991+
if (result == null)
992+
Assert.Fail("Asset.Fetch with AssetFields and IncludeMetadata did not return a result.");
993+
Assert.NotNull(result.Uid);
994+
Assert.NotEmpty(result.FileName);
995+
}
996+
997+
[Fact]
998+
public async Task AssetFields_AssetLibrary_ChainedWithIncludeMetadata_RequestSucceeds()
999+
{
1000+
ContentstackCollection<Asset> assets = await client.AssetLibrary()
1001+
.AssetFields("user_defined_fields")
1002+
.IncludeMetadata()
1003+
.FetchAll();
1004+
1005+
if (assets == null)
1006+
Assert.Fail("AssetLibrary.FetchAll with AssetFields and IncludeMetadata did not return a result.");
1007+
Assert.NotNull(assets.Items);
1008+
}
1009+
1010+
[Fact]
1011+
public async Task AssetFields_SingleField_RequestSucceeds()
1012+
{
1013+
string uid = await FetchAssetUID();
1014+
Asset asset = client.Asset(uid);
1015+
asset.AssetFields("user_defined_fields");
1016+
Asset result = await asset.Fetch();
1017+
1018+
if (result == null)
1019+
Assert.Fail("Asset.Fetch with AssetFields single field did not return a result.");
1020+
Assert.NotNull(result.Uid);
1021+
Assert.NotEmpty(result.FileName);
1022+
}
1023+
1024+
[Fact]
1025+
public async Task AssetFields_AssetLibrary_SingleField_RequestSucceeds()
1026+
{
1027+
AssetLibrary assetLibrary = client.AssetLibrary();
1028+
assetLibrary.AssetFields("user_defined_fields");
1029+
ContentstackCollection<Asset> assets = await assetLibrary.FetchAll();
1030+
1031+
if (assets == null)
1032+
Assert.Fail("AssetLibrary.FetchAll with AssetFields single field did not return a result.");
1033+
Assert.NotNull(assets.Items);
1034+
}
1035+
1036+
[Fact]
1037+
public async Task AssetFields_WithNoArguments_RequestSucceeds()
1038+
{
1039+
string uid = await FetchAssetUID();
1040+
Asset asset = client.Asset(uid);
1041+
asset.AssetFields();
1042+
Asset result = await asset.Fetch();
1043+
1044+
if (result == null)
1045+
Assert.Fail("Asset.Fetch with AssetFields() no arguments did not return a result.");
1046+
Assert.NotNull(result.Uid);
1047+
}
1048+
1049+
[Fact]
1050+
public async Task AssetFields_AssetLibrary_WithNoArguments_RequestSucceeds()
1051+
{
1052+
AssetLibrary assetLibrary = client.AssetLibrary();
1053+
assetLibrary.AssetFields();
1054+
ContentstackCollection<Asset> assets = await assetLibrary.FetchAll();
1055+
1056+
if (assets == null)
1057+
Assert.Fail("AssetLibrary.FetchAll with AssetFields() no arguments did not return a result.");
1058+
Assert.NotNull(assets.Items);
1059+
}
1060+
1061+
[Fact]
1062+
public async Task AssetFields_WithNull_RequestSucceeds()
1063+
{
1064+
string uid = await FetchAssetUID();
1065+
Asset asset = client.Asset(uid);
1066+
asset.AssetFields(null);
1067+
Asset result = await asset.Fetch();
1068+
1069+
if (result == null)
1070+
Assert.Fail("Asset.Fetch with AssetFields(null) did not return a result.");
1071+
Assert.NotNull(result.Uid);
1072+
}
1073+
1074+
[Fact]
1075+
public async Task AssetFields_WithEmptyArray_RequestSucceeds()
1076+
{
1077+
string uid = await FetchAssetUID();
1078+
Asset asset = client.Asset(uid);
1079+
asset.AssetFields(new string[0]);
1080+
Asset result = await asset.Fetch();
1081+
1082+
if (result == null)
1083+
Assert.Fail("Asset.Fetch with AssetFields(empty array) did not return a result.");
1084+
Assert.NotNull(result.Uid);
1085+
}
1086+
1087+
[Fact]
1088+
public async Task AssetFields_AssetLibrary_WithNull_RequestSucceeds()
1089+
{
1090+
AssetLibrary assetLibrary = client.AssetLibrary();
1091+
assetLibrary.AssetFields(null);
1092+
ContentstackCollection<Asset> assets = await assetLibrary.FetchAll();
1093+
1094+
if (assets == null)
1095+
Assert.Fail("AssetLibrary.FetchAll with AssetFields(null) did not return a result.");
1096+
Assert.NotNull(assets.Items);
1097+
}
1098+
1099+
[Fact]
1100+
public async Task AssetFields_AssetLibrary_WithEmptyArray_RequestSucceeds()
1101+
{
1102+
AssetLibrary assetLibrary = client.AssetLibrary();
1103+
assetLibrary.AssetFields(new string[0]);
1104+
ContentstackCollection<Asset> assets = await assetLibrary.FetchAll();
1105+
1106+
if (assets == null)
1107+
Assert.Fail("AssetLibrary.FetchAll with AssetFields(empty array) did not return a result.");
1108+
Assert.NotNull(assets.Items);
1109+
}
9541110
}
9551111
}

Contentstack.Core.Tests/Contentstack.Core.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<PackageReference Include="AutoFixture" Version="4.18.1" />
2929
<PackageReference Include="AutoFixture.AutoMoq" Version="4.18.1" />
3030
<PackageReference Include="Moq" Version="4.20.72" />
31+
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
3132
</ItemGroup>
3233

3334
<ItemGroup>

Contentstack.Core.Tests/EntryTest.cs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using Xunit;
33
using Contentstack.Core.Models;
44
using System.Threading.Tasks;
@@ -457,5 +457,97 @@ public async Task GetMetadata()
457457
Assert.True(true, "GetMetadata() returns a valid dictionary (may be empty)");
458458
}
459459
}
460+
461+
[Fact]
462+
public async Task AssetFields_SingleEntry_RequestSucceeds()
463+
{
464+
ContentType contenttype = client.ContentType(source);
465+
string uid = await GetUID("source1");
466+
Entry sourceEntry = contenttype.Entry(uid);
467+
468+
sourceEntry.AssetFields("user_defined_fields", "visual_markups");
469+
var result = await sourceEntry.Fetch<Entry>();
470+
471+
if (result == null)
472+
Assert.Fail("Entry.Fetch with AssetFields did not return a result.");
473+
Assert.NotNull(result.Uid);
474+
}
475+
476+
[Fact]
477+
public async Task AssetFields_ChainedWithIncludeMetadata_RequestSucceeds()
478+
{
479+
ContentType contenttype = client.ContentType(source);
480+
string uid = await GetUID("source1");
481+
Entry sourceEntry = contenttype.Entry(uid);
482+
483+
var result = await sourceEntry
484+
.AssetFields("user_defined_fields")
485+
.IncludeMetadata()
486+
.Fetch<Entry>();
487+
488+
if (result == null)
489+
Assert.Fail("Entry.Fetch with AssetFields and IncludeMetadata did not return a result.");
490+
Assert.NotNull(result.Uid);
491+
}
492+
493+
[Fact]
494+
public async Task AssetFields_SingleField_RequestSucceeds()
495+
{
496+
ContentType contenttype = client.ContentType(source);
497+
string uid = await GetUID("source1");
498+
Entry sourceEntry = contenttype.Entry(uid);
499+
500+
sourceEntry.AssetFields("user_defined_fields");
501+
var result = await sourceEntry.Fetch<Entry>();
502+
503+
if (result == null)
504+
Assert.Fail("Entry.Fetch with AssetFields single field did not return a result.");
505+
Assert.NotNull(result.Uid);
506+
}
507+
508+
[Fact]
509+
public async Task AssetFields_WithNoArguments_RequestSucceeds()
510+
{
511+
ContentType contenttype = client.ContentType(source);
512+
string uid = await GetUID("source1");
513+
Entry sourceEntry = contenttype.Entry(uid);
514+
515+
sourceEntry.AssetFields();
516+
var result = await sourceEntry.Fetch<Entry>();
517+
518+
if (result == null)
519+
Assert.Fail("Entry.Fetch with AssetFields() no arguments did not return a result.");
520+
Assert.NotNull(result.Uid);
521+
}
522+
523+
[Fact]
524+
public async Task AssetFields_WithNull_RequestSucceeds()
525+
{
526+
ContentType contenttype = client.ContentType(source);
527+
string uid = await GetUID("source1");
528+
Entry sourceEntry = contenttype.Entry(uid);
529+
530+
sourceEntry.AssetFields(null);
531+
var result = await sourceEntry.Fetch<Entry>();
532+
533+
if (result == null)
534+
Assert.Fail("Entry.Fetch with AssetFields(null) did not return a result.");
535+
Assert.NotNull(result.Uid);
536+
}
537+
538+
[Fact]
539+
public async Task AssetFields_WithEmptyArray_RequestSucceeds()
540+
{
541+
ContentType contenttype = client.ContentType(source);
542+
string uid = await GetUID("source1");
543+
Entry sourceEntry = contenttype.Entry(uid);
544+
545+
sourceEntry.AssetFields(new string[0]);
546+
var result = await sourceEntry.Fetch<Entry>();
547+
548+
if (result == null)
549+
Assert.Fail("Entry.Fetch with AssetFields(empty array) did not return a result.");
550+
Assert.NotNull(result.Uid);
551+
}
460552
}
461553
}

Contentstack.Core.Tests/QueryTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,18 @@ public async Task IncludeSchema()
16191619
// The exact assertion depends on your data structure
16201620
}
16211621
}
1622+
1623+
[Fact]
1624+
public async Task AssetFieldsQueryEntriesRequestSucceeds()
1625+
{
1626+
Query query = client.ContentType(source).Query();
1627+
query.AssetFields("user_defined_fields", "visual_markups");
1628+
var result = await query.Find<Entry>();
1629+
1630+
if (result == null)
1631+
Assert.Fail("Query.Find with AssetFields did not return a result.");
1632+
Assert.NotNull(result.Items);
1633+
}
16221634
}
16231635
}
16241636

0 commit comments

Comments
 (0)