Kontent.Ai.ModelGenerator.Core 10.3.0-beta-1

This is a prerelease version of Kontent.Ai.ModelGenerator.Core.
dotnet add package Kontent.Ai.ModelGenerator.Core --version 10.3.0-beta-1
                    
NuGet\Install-Package Kontent.Ai.ModelGenerator.Core -Version 10.3.0-beta-1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kontent.Ai.ModelGenerator.Core" Version="10.3.0-beta-1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kontent.Ai.ModelGenerator.Core" Version="10.3.0-beta-1" />
                    
Directory.Packages.props
<PackageReference Include="Kontent.Ai.ModelGenerator.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kontent.Ai.ModelGenerator.Core --version 10.3.0-beta-1
                    
#r "nuget: Kontent.Ai.ModelGenerator.Core, 10.3.0-beta-1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kontent.Ai.ModelGenerator.Core@10.3.0-beta-1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kontent.Ai.ModelGenerator.Core&version=10.3.0-beta-1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Kontent.Ai.ModelGenerator.Core&version=10.3.0-beta-1&prerelease
                    
Install as a Cake Tool

Kontent.ai model generator utility for .NET

NuGet License Build & Test codecov Contributors Last commit GitHub Issues Stack Overflow Discord

This utility generates strongly-typed record-based models for:

Management mode emits code that references the IElementsModel marker, the [KontentType] / [KontentElement] / [KontentEnumValue] attributes, and the value types (RichTextValue, AssetReference, Reference, UrlSlugValue, DateTimeValue, CustomValue) shipped by Kontent.Ai.Management 9.0.0-beta-1. Generated management models require Kontent.Ai.Management 9.0.0-beta-1 or newer — they won't compile against v8.2.0 or earlier. The mode is a beta: the generated shapes may still change before the SDK stabilizes.

If you need models for the legacy Delivery SDK (v18.x and earlier) or for Extended Delivery, use the previous stable release.

What's New in Updated Delivery Models

The generated models use modern C# features and patterns:

  • Records - Immutable record types with { get; init; } accessors
  • Modern types - RichTextContent, Asset, TaxonomyTerm, IEmbeddedContent
  • Partial records - Easily extendable without modifying generated code
  • ContentTypeCodename attribute - For source-generated TypeProvider discovery
  • ContentTypeCodename constant - Access the content type codename at compile time (usable in switch/case labels, attribute arguments, and other contexts that require a compile-time constant) without reflection

If an element codename would produce a property or constant that collides with the built-in ContentTypeCodename constant (e.g., an element named content_type_codename or content_type), the element's member is automatically prefixed with an underscore (_ContentTypeCodename) to avoid conflicts. The [JsonPropertyName] attribute ensures deserialization still works correctly.

Installation & Usage

The recommended way of obtaining this tool is installing it as a .NET Tool. You can install it as a global tool or per project as a local tool.

Global Tool
dotnet tool install -g Kontent.Ai.ModelGenerator

Delivery (default):

KontentModelGenerator --environmentId "<environmentId>" \
    [--namespace "<custom-namespace>"] \
    [--outputdir "<output-directory>"] \
    [--baseRecord "<base-record-name>"] \
    [--nullability strict|semantic]

Management (beta — see Management Models):

KontentModelGenerator --management \
    --environmentId "<environmentId>" \
    --apiKey "<management-api-key>" \
    [--namespace "<custom-namespace>"] \
    [--outputdir "<output-directory>"]
Local Tool
dotnet new tool-manifest
dotnet tool install Kontent.Ai.ModelGenerator
dotnet tool run KontentModelGenerator --environmentId "<environmentId>" \
    [--namespace "<custom-namespace>"] \
    [--outputdir "<output-directory>"] \
    [--baseRecord "<base-record-name>"] \
    [--nullability strict|semantic]

Standalone apps for Windows, Linux, macOS

Self-contained apps are an ideal choice for machines without any version of .NET installed.

Latest release: Download

<details> <summary>Building a self-contained binary for a specific platform</summary>

  • Clone the repository
  • Navigate to src/Kontent.Ai.ModelGenerator
  • dotnet build -r <RID> to build (see the list of all RIDs)
  • dotnet publish -c release -r <RID> to publish

</details>

Parameters

Short key Long key Required Default value Description
-i --environmentId Yes null A GUID that can be found in Kontent.ai → Environment settings → Environment ID
-m --management No false Switches the generator to Management mode. Emits models for the Management SDK instead of Delivery. See Management Models.
-k --apiKey Mgmt only null Management API key (required when -m / --management is used).
-n --namespace No KontentAiModels A name of the C# namespace
-o --outputdir No ./ An output folder path
-t --withtypeprovider No false (Obsolete) TypeProvider is now source-generated by the Delivery SDK.
-b, -r --baseRecord No null If provided, a base record will be created and all generated records will derive from it via partial extender records
--nullability No strict Either strict or semantic. Delivery mode only. See Nullability mode.

CLI Syntax

Short keys such as -n "MyModels" are interchangeable with the long keys --namespace "MyModels". Other possible syntax is -n=MyModels or --namespace=MyModels. Parameter values are case-insensitive. To see all aspects of the syntax, see the MS docs.

Config file

These parameters can also be set via the appSettings.json file located in the same directory as the executable file. Command-line parameters always take precedence.

Advanced configuration (Preview API, Secure API)

There are two ways of configuring advanced Delivery SDK options (such as secure API access, preview API access, and others):

  1. Command-line arguments:

    --DeliveryOptions:UseSecureAccess true --DeliveryOptions:SecureAccessApiKey <SecuredApiKey>
    
  2. appSettings.json - suitable for the standalone app release

Generated Model Example (Delivery)

For the Management-mode equivalent, jump to Management Models.

Generated file: Article.cs

// <auto-generated>
// This code was generated by Kontent.ai model generator tool
// (see https://github.com/kontent-ai/model-generator-net).
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// To extend this record, create a separate partial record with the same name.
// </auto-generated>

#nullable enable

using System.Collections.Generic;
using System.Text.Json.Serialization;
using Kontent.Ai.Delivery.Abstractions;
using Kontent.Ai.Delivery.Attributes;
using Kontent.Ai.Delivery.ContentItems;
using Kontent.Ai.Delivery.ContentItems.RichText;
using Kontent.Ai.Delivery.SharedModels;

namespace KontentAiModels;

[ContentTypeCodename("article")]
public partial record Article
{
    public const string BodyCopyCodename = "body_copy";
    public const string CustomTrackingCodeCodename = "custom_tracking_code";
    public const string PersonasCodename = "personas";
    public const string PostDateCodename = "post_date";
    public const string RelatedArticlesCodename = "related_articles";
    public const string TeaserImageCodename = "teaser_image";
    public const string TitleCodename = "title";
    public const string UrlPatternCodename = "url_pattern";

    public const string ContentTypeCodename = "article";

    [JsonPropertyName("body_copy")]
    public RichTextContent? BodyCopy { get; init; }
    [JsonPropertyName("custom_tracking_code")]
    public string? CustomTrackingCode { get; init; }
    [JsonPropertyName("personas")]
    public IEnumerable<TaxonomyTerm>? Personas { get; init; }
    [JsonPropertyName("post_date")]
    public DateTimeContent? PostDate { get; init; }
    [JsonPropertyName("related_articles")]
    public IEnumerable<IEmbeddedContent>? RelatedArticles { get; init; }
    [JsonPropertyName("teaser_image")]
    public IEnumerable<Asset>? TeaserImage { get; init; }
    [JsonPropertyName("title")]
    public string? Title { get; init; }
    [JsonPropertyName("url_pattern")]
    public string? UrlPattern { get; init; }
}

Nullability mode

The generator supports two nullability strategies for element properties via the --nullability flag:

strict (default)

Every element property is generated as a nullable type — string?, RichTextContent?, IEnumerable<Asset>?, etc. This is the conservative default. It's also useful if you use the Delivery SDK's projection features (WithElements / WithoutElements) and want the type system to distinguish "not fetched" (null) from "fetched and empty" — projected-away elements surface as null at runtime.

public string? Title { get; init; }
public RichTextContent? BodyCopy { get; init; }
public IEnumerable<IEmbeddedContent>? RelatedArticles { get; init; }

semantic

Element properties match the runtime semantics of the Delivery API: empty text, rich text and collection elements always come back populated, so they're generated as non-nullable with sensible default initializers. Numbers, dates and custom elements can be genuinely unset, so they remain nullable.

public string Title { get; init; } = string.Empty;
public RichTextContent BodyCopy { get; init; } = RichTextContent.Empty;
public IEnumerable<IEmbeddedContent> RelatedArticles { get; init; } = [];
public double? Rating { get; init; }
public DateTimeContent? PostDate { get; init; }
public string? CustomTrackingCode { get; init; }

When combined with projection (WithElements / WithoutElements), an omitted element surfaces as the type's default ("", [], RichTextContent.Empty) rather than null — so "not fetched" and "fetched and empty" look the same. That's fine if your code doesn't branch on that distinction; if it does, prefer strict.

--nullability semantic requires Delivery SDK 19.2.0+ (for RichTextContent.Empty). It will become the default in the next major version of the model generator.

Customizing Generated Models

Since the generated models are partial records, you can extend them by creating your own partial record file:

Generated file: Article.cs (auto-generated)

namespace KontentAiModels;

[ContentTypeCodename("article")]
public partial record Article
{
    public const string TitleCodename = "title";
    // ... other constants and properties

    public const string ContentTypeCodename = "article";

    [JsonPropertyName("title")]
    public string? Title { get; init; }
}

Your custom file: Article.Custom.cs (your customizations)

namespace KontentAiModels;

public partial record Article
{
    // Add computed properties
    public string Slug => Title?.ToLowerInvariant().Replace(" ", "-") ?? string.Empty;

    // Add custom methods
    public bool IsPublished() => PostDate is { DateTime: var dt } && dt <= DateTime.Now;

    // Add validation
    public bool IsValid() => !string.IsNullOrEmpty(Title) && BodyCopy != null;
}

The generator creates the base model, and you maintain customizations in separate files that won't be overwritten.

Management Models

Beta. The emitted code references types and attributes shipped by Kontent.Ai.Management 9.0.0-beta-1IElementsModel, [KontentType], [KontentElement], [KontentEnumValue], RichTextValue, AssetReference, Reference, UrlSlugValue, DateTimeValue, and CustomValue. Generated models require Kontent.Ai.Management 9.0.0-beta-1 or newer and won't compile against v8.2.0 or earlier. The generated shapes may still change before the SDK stabilizes.

When you need to write content to Kontent.ai (create / update / delete / publish via the Management API), pass -m / --management to switch the generator from Delivery mode into Management mode. The emitter produces strongly-typed records you can construct with object-initializer syntax and pass to IManagementClient.

CLI

KontentModelGenerator --management \
    --environmentId "<environmentId>" \
    --apiKey "<management-api-key>" \
    [--namespace "<custom-namespace>"] \
    [--outputdir "<output-directory>"]

What's different from Delivery models

Delivery Management
Use case Read content, frontend rendering CRUD via the Management API
Marker interface None IElementsModel (empty marker)
Element identity [JsonPropertyName("codename")] [KontentElement(codename, id)] — both required (codename for request serialization, ID for response deserialization)
Type-level metadata [ContentTypeCodename] [KontentType(codename)]
Collections IEnumerable<T>? IEnumerable<T>?
Element constraints Implicit at API layer Not mirrored on the model. Content-model rules (length, regex, allowed types, count limits, asset rules, ...) are enforced server-side by the Management API — the generated models carry identity only.
Multiple-choice IEnumerable<MultipleChoiceOption>? Per-element enum ([KontentEnumValue] members) + IEnumerable<{ContentType}{Element}>?
Snippets Implicit; values come back flattened Flattened at generation time; properties carry {snippet}__{element} codenames
Required elements Not exposed Not enforced on the model. is_required is a publish-workflow gate in MAPI, not an upsert-shape constraint — every property stays nullable so partial draft saves work.

Generated model example

Generated file: Article.cs

// <auto-generated/>

#nullable enable

using System;
using System.Collections.Generic;
using Kontent.Ai.Management;
using Kontent.Ai.Management.Annotations;
using Kontent.Ai.Management.Models.Content;

namespace MyProject.Models;

[KontentType("article")]
public sealed partial record Article : IElementsModel
{
    [KontentElement("body", "7ed15846-...")]
    public RichTextValue? Body { get; init; }

    [KontentElement("category", "f6d310a3-...")]
    public IEnumerable<ArticleCategory>? Category { get; init; }

    [KontentElement("featured_image", "8d2c...")]
    public IEnumerable<AssetReference>? FeaturedImage { get; init; }

    [KontentElement("priority", "88ae3d9b-...")]
    public decimal? Priority { get; init; }

    [KontentElement("publish_at", "b12f0a44-...")]
    public DateTimeValue? PublishAt { get; init; }

    [KontentElement("rating_widget", "c93b71de-...")]
    public CustomValue? RatingWidget { get; init; }

    [KontentElement("related_teasers", "a3155ec4-...")]
    public IEnumerable<Reference>? RelatedTeasers { get; init; }

    [KontentElement("seo__meta_title", "09398b24-...")]
    public string? SeoMetaTitle { get; init; }

    [KontentElement("tags", "1314993e-...")]
    public IEnumerable<Reference>? Tags { get; init; }

    [KontentElement("title", "a47451eb-...")]
    public string? Title { get; init; }

    [KontentElement("url", "e5a8c0f1-...")]
    public UrlSlugValue? Url { get; init; }
}

public enum ArticleCategory
{
    [KontentEnumValue("news", "d65a2212-...")] News,
    [KontentEnumValue("release", "709b1208-...")] Release,
    [KontentEnumValue("blog", "ae79c5a6-...")] Blog,
}

Notes

  • Models are environment-specific by virtue of their element IDs. Cloning an environment via data-ops produces logically identical content models with different element IDs — regenerate after cloning.
  • Snippets are flattened. If your content type uses an seo snippet that contributes meta_title and meta_description, the generated record has SeoMetaTitle and SeoMetaDescription properties; the [KontentElement] attributes carry the seo__meta_title / seo__meta_description codenames the API expects.
  • Content-model constraints are not on the model. Length, regex, allowed types, count limits, asset rules, and the like are enforced server-side by the Management API and surfaced via IManagementResult — the generated records carry element identity and value types only.

Need Legacy Delivery SDK or Extended Delivery Support?

For these use cases, use the previous stable release:

  • Legacy Delivery SDK (v18.x and earlier) models
  • Extended Delivery models

Feedback & Contributing

Found a bug or have a feature request? Open an issue. Pull requests are welcome!

Wall of Fame

We would like to express our thanks to the following people who contributed and made the project possible:

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.3.0-beta-1 63 6/26/2026
10.2.0 113 5/5/2026
10.1.1 129 4/23/2026
10.1.0 120 4/21/2026
10.0.0 114 4/19/2026
10.0.0-beta-5 122 3/3/2026
10.0.0-beta-4 117 3/3/2026
10.0.0-beta-3 110 2/20/2026
10.0.0-beta-2 123 1/11/2026
10.0.0-beta 218 10/26/2025
9.0.0 1,131 4/8/2025
8.4.0 17,233 12/12/2023
8.3.3 1,735 6/4/2023
8.3.2 280 5/18/2023
8.3.1 295 5/5/2023
8.3.0 328 4/20/2023
8.3.0-beta.6 214 4/13/2023
8.3.0-beta.3 209 2/16/2023
8.3.0-beta.2 215 2/16/2023
8.3.0-beta.1 206 2/16/2023
Loading failed