What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
SDKs
Get, list, create, update and delete content models and component models with the Agility CMS .NET Management SDK 2.0, and look up the field types a model can use.
This page has moved — the Management SDK is now documented elsewhere. The JavaScript and .NET guides have been merged into a single set with per-language code tabs. Read the current guide.
client.Models reads and changes the models in an instance: the content models that content items use, and the component models that page components use.
Note: Upgrading from 1.x?
modelMethodsis nowclient.Models, and every method takes the instance GUID first. See Migrating to 2.0.
A model defines fields. A content model is used by content items. A component model (some API and SDK names still say Module) is used by page components. To manage the containers that hold content items of a model, see Containers.
The examples assume a client created as shown in the Intro, and guid set to your instance GUID. The model types are in the Agility.Management.Sdk.Models namespace:
using Agility.Management.Sdk;
using Agility.Management.Sdk.Models;
Every method also takes an optional CancellationToken cancellationToken as its last parameter. The signatures below leave it out.
ContentModel model = await client.Models.GetModelAsync(guid, modelId);
Console.WriteLine($"{model.DisplayName}: {model.Fields?.Count} fields");
Signature: Task<ContentModel> GetModelAsync(string instanceGuid, int modelId)
ContentModel model = await client.Models.GetModelByReferenceNameAsync(guid, "BlogPost");
Console.WriteLine($"{model.DisplayName} (ID: {model.Id})");
Signature: Task<ContentModel> GetModelByReferenceNameAsync(string instanceGuid, string referenceName)
Note: In 1.x, these methods returned
nullwhen there was no model. In 2.0 they never returnnull. If the API returns an error or an empty response, they throw anAgilityManagementException.
List<ContentModel> contentModels = await client.Models.GetContentModelsAsync(guid, includeDefaults: false);
foreach (var model in contentModels)
{
Console.WriteLine($"{model.ReferenceName} - {model.DisplayName}");
}
| Parameter | What it does |
|---|---|
includeDefaults | Include Agility's built-in models. Default false. |
includeModules | Include component models too. Leave it null to use the API's default, which leaves them out. |
updatedSince | Return only models changed after this time. Leave it null to get every model. |
To get only the models changed in the last day:
var changed = await client.Models.GetContentModelsAsync(guid, updatedSince: DateTime.UtcNow.AddDays(-1));
Signature: Task<List<ContentModel>> GetContentModelsAsync(string instanceGuid, bool includeDefaults = false, bool? includeModules = null, DateTime? updatedSince = null)
Get the component models that page components use. This replaces GetPageModules from 1.x.
List<ContentModel> componentModels = await client.Models.GetComponentModelsAsync(guid);
foreach (var model in componentModels)
{
Console.WriteLine(model.ReferenceName);
}
Pass includeDefault: true to include Agility's built-in components.
Signature: Task<List<ContentModel>> GetComponentModelsAsync(string instanceGuid, bool includeDefault = false)
GetFieldTypesAsync returns the names of the field types a model can use. Use these names as ContentModelField.Type.
List<string> fieldTypes = await client.Models.GetFieldTypesAsync(guid);
Signature: Task<List<string>> GetFieldTypesAsync(string instanceGuid)
GetUsedFieldTypesAsync lists the field types that the instance's models use, including custom fields. The API doesn't describe the shape of this response, so the SDK returns it as JSON.
using System.Text.Json.Nodes;
JsonNode? used = await client.Models.GetUsedFieldTypesAsync(guid);
Console.WriteLine(used?.ToJsonString());
includeDefaults and includeModules control whether built-in models and component models are included. Leave them null to use the API's defaults, which include both.
Signature: Task<JsonNode?> GetUsedFieldTypesAsync(string instanceGuid, bool? includeDefaults = null, bool? includeModules = null)
SaveModelAsync creates or updates a model and returns the saved model. To create one, set Id to 0.
ContentModel saved = await client.Models.SaveModelAsync(guid, new ContentModel
{
Id = 0,
DisplayName = "Blog Post",
ReferenceName = "BlogPost",
Fields =
[
new ContentModelField
{
Name = "Title",
Label = "Title",
Type = "Text",
IsDataField = true,
Editable = true,
Settings = new() { ["Required"] = "True" },
},
],
});
Console.WriteLine($"Created model ID: {saved.Id}");
Field settings, such as whether a field is required, go in the field's Settings dictionary as strings.
Signature: Task<ContentModel> SaveModelAsync(string instanceGuid, ContentModel model)
The field list you send is the model's complete field list. To add a field, read the model, change it, and save the whole model back.
ContentModel model = await client.Models.GetModelByReferenceNameAsync(guid, "BlogPost");
model.Fields ??= [];
model.Fields.Add(new ContentModelField
{
Name = "Summary",
Label = "Summary",
Type = "Text",
IsDataField = true,
Editable = true,
Settings = new() { ["Required"] = "False" },
});
ContentModel updated = await client.Models.SaveModelAsync(guid, model);
⚠️ Don't save a model with a partial field list. A model you build from scratch with only the field you want to add replaces the model's fields with that one field.
await client.Models.DeleteModelAsync(guid, modelId);
The method returns nothing. If the delete fails, it throws an AgilityManagementException.
Signature: Task DeleteModelAsync(string instanceGuid, int modelId)
Every error from the API or the network throws an AgilityManagementException. It carries the HTTP status code, the API's own message and a request ID.
try
{
var model = await client.Models.GetModelByReferenceNameAsync(guid, "BlogPost");
}
catch (AgilityManagementException ex)
{
Console.Error.WriteLine($"{ex.StatusCode}: {ex.ApiMessage} (request {ex.RequestId})");
}
Reads are retried automatically on temporary failures. Saves and deletes are never retried. See the Intro for the full list of exceptions and the retry rules.
1.x (client.modelMethods) | 2.0 (client.Models) |
|---|---|
GetContentModel(id, guid) | GetModelAsync(guid, modelId) |
GetModelByReferenceName(name, guid) | GetModelByReferenceNameAsync(guid, referenceName) |
GetContentModules(includeDefaults, guid, includeModules) | GetContentModelsAsync(guid, includeDefaults, includeModules) |
GetPageModules(guid, includeDefault) | GetComponentModelsAsync(guid, includeDefault) |
SaveModel(model, guid) | SaveModelAsync(guid, model) |
DeleteModel(id, guid) | DeleteModelAsync(guid, modelId) |
The Model and ModelField classes are now ContentModel and ContentModelField, and Model.ID is now ContentModel.Id. GetFieldTypesAsync, GetUsedFieldTypesAsync and the updatedSince filter are new in 2.0.