Skip to content

Latest commit

 

History

146 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenAPI Code Generator

A fast, opinionated C# code generator for OpenAPI specifications.

NuGet NuGet Downloads License

DocumentationInstallationQuick StartChangelog


OpenAPI Code Generator transforms OpenAPI 3.x specifications into clean, modern C# code — generating records, enums, and primitive type aliases with full nullable reference type support and built-in System.Text.Json attributes and converters where needed.

Features

  • Modern C# output — Generates record types with init-only properties
  • OpenAPI 3.x support — JSON and YAML specifications
  • Nullable reference types — Full #nullable enable support
  • System.Text.Json — Built-in [JsonPropertyName] and [JsonConverter] attributes
  • String enums — Generates [JsonStringEnumConverter] backed enums
  • Immutable collectionsIReadOnlyList<T> and IReadOnlyDictionary<string, T> by default
  • Composition support — Handles allOf, oneOf, and anyOf schemas
  • URL input — Fetch and generate directly from remote OpenAPI specs
  • Zero dependencies at runtime — Generated code only needs System.Text.Json

Installation

Install as a global .NET tool:

dotnet tool install --global Nikcio.OpenApiCodeGen

Or as a local tool in your project:

dotnet new tool-manifest
dotnet tool install Nikcio.OpenApiCodeGen

Quick Start

Generate C# models from a local spec file:

openapi-codegen petstore.yaml -o Models.cs

Generate from a remote URL with a custom namespace:

openapi-codegen https://petstore3.swagger.io/api/v3/openapi.json -o PetStore.cs -n MyApp.Models

Output to stdout:

openapi-codegen spec.yaml

CLI Reference

USAGE:
    openapi-codegen [OPTIONS] <input> [output]
    openapi-codegen --input <file-or-url> --output <file>

ARGUMENTS:
    <input>     Path or URL to an OpenAPI specification (JSON or YAML)
    [output]    Output file path (defaults to stdout)

OPTIONS:
    -i, --input <path>          Input OpenAPI spec file or URL
    -o, --output <path>         Output C# file path
    -n, --namespace <name>      C# namespace (default: GeneratedModels)
        --model-prefix <prefix> Prefix every generated model type name
        --include-schema <name> Include only the named schema and its dependencies (repeatable)
        --no-doc-comments       Disable XML doc comment generation
        --no-header             Disable auto-generated file header
        --no-default-non-nullable  Don't treat defaults as non-nullable
        --no-add-default-values     Don't add default values from OpenAPI to properties
        --mutable-arrays        Use List<T> instead of IReadOnlyList<T>
        --mutable-dictionaries  Use Dictionary<K,V> instead of IReadOnlyDictionary<K,V>
        --omit-json-attributes  Skip [JsonPropertyName] on generated properties
        --inline-type-aliases   Inline primitive aliases instead of emitting wrapper types
        --no-validation-attributes  Skip validation attributes from OpenAPI constraints
        --no-deprecated-attributes  Skip [Obsolete] on deprecated schemas and properties
    -v, --version               Show version information
    -h, --help                  Show this help message

Library Usage

You can also reference the core library directly for programmatic code generation:

using OpenApiCodeGenerator;

var generator = new CSharpSchemaGenerator(new GeneratorOptions
{
    Namespace = "MyApp.Models",
    ModelPrefix = "Api",
    IncludeSchemas = ["User", "Address"],
    GenerateDocComments = true
});

string code = generator.GenerateFromFile("petstore.yaml");
File.WriteAllText("Models.cs", code);

Example Output

Given a simple Petstore OpenAPI spec, the generator produces:

// <auto-generated>
// This file was auto-generated by OpenApiCodeGenerator.
// Do not make direct changes to the file.
// </auto-generated>

#nullable enable

using System.Text.Json.Serialization;

namespace Generated.Petstore;

/// <summary>
/// Order Status
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum OrderStatus
{
    [JsonStringEnumMemberName("placed")]
    Placed,
    [JsonStringEnumMemberName("approved")]
    Approved,
    [JsonStringEnumMemberName("delivered")]
    Delivered
}

/// <summary>
/// pet status in the store
/// </summary>
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum PetStatus
{
    [JsonStringEnumMemberName("available")]
    Available,
    [JsonStringEnumMemberName("pending")]
    Pending,
    [JsonStringEnumMemberName("sold")]
    Sold
}

public record Order
{
    [JsonPropertyName("id")]
    public long? Id { get; init; }

    [JsonPropertyName("petId")]
    public long? PetId { get; init; }

    [JsonPropertyName("quantity")]
    public int? Quantity { get; init; }

    [JsonPropertyName("shipDate")]
    public DateTimeOffset? ShipDate { get; init; }

    /// <summary>
    /// Order Status
    /// </summary>
    [JsonPropertyName("status")]
    public OrderStatus? Status { get; init; }

    [JsonPropertyName("complete")]
    public bool? Complete { get; init; }

}

public record Category
{
    [JsonPropertyName("id")]
    public long? Id { get; init; }

    [JsonPropertyName("name")]
    public string? Name { get; init; }

}

public record User
{
    [JsonPropertyName("id")]
    public long? Id { get; init; }

    [JsonPropertyName("username")]
    public string? Username { get; init; }

    [JsonPropertyName("firstName")]
    public string? FirstName { get; init; }

    [JsonPropertyName("lastName")]
    public string? LastName { get; init; }

    [JsonPropertyName("email")]
    public string? Email { get; init; }

    [JsonPropertyName("password")]
    public string? Password { get; init; }

    [JsonPropertyName("phone")]
    public string? Phone { get; init; }

    /// <summary>
    /// User Status
    /// </summary>
    [JsonPropertyName("userStatus")]
    public int? UserStatus { get; init; }

}

public record Tag
{
    [JsonPropertyName("id")]
    public long? Id { get; init; }

    [JsonPropertyName("name")]
    public string? Name { get; init; }

}

public record Pet
{
    [JsonPropertyName("id")]
    public long? Id { get; init; }

    [JsonPropertyName("name")]
    public required string Name { get; init; }

    [JsonPropertyName("category")]
    public Category? Category { get; init; }

    [JsonPropertyName("photoUrls")]
    public required IReadOnlyList<string> PhotoUrls { get; init; }

    [JsonPropertyName("tags")]
    public IReadOnlyList<Tag>? Tags { get; init; }

    /// <summary>
    /// pet status in the store
    /// </summary>
    [JsonPropertyName("status")]
    public PetStatus? Status { get; init; }

}

public record ApiResponse
{
    [JsonPropertyName("code")]
    public int? Code { get; init; }

    [JsonPropertyName("type")]
    public string? Type { get; init; }

    [JsonPropertyName("message")]
    public string? Message { get; init; }

}

Configuration Options

Option Default Description
Namespace GeneratedModels C# namespace for generated types
ModelPrefix null Prefix every generated model type name
GenerateDocComments true Include XML doc comments from OpenAPI descriptions
GenerateFileHeader true Include auto-generated file header
DefaultNonNullable true Treat properties with defaults as non-nullable
UseImmutableArrays true Use IReadOnlyList<T> for arrays
UseImmutableDictionaries true Use IReadOnlyDictionary<string, T> for maps
AddDefaultValuesToProperties true Add default values from OpenAPI to generated properties
IncludeSchemas null Generate only the named schemas and their dependencies
OmitJsonPropertyNameAttributes false Skip [JsonPropertyName] on generated properties
InlinePrimitiveTypeAliases false Inline primitive aliases instead of emitting wrapper types
EmitValidationAttributes true Emit validation attributes ([Range], [StringLength], etc.) from OpenAPI constraints
EmitObsoleteAttribute true Emit [Obsolete] on deprecated schemas and properties

Native AOT

The CLI is Native AOT compatible. Publish a fast-starting, self-contained native executable with:

dotnet publish src/OpenApiCodeGenerator.Cli -c Release -r <RID>

Replace <RID> with your target runtime ID, e.g. win-x64, linux-x64, or osx-arm64. Native AOT publishing requires the platform toolchain described in the Native AOT prerequisites. The CI pipeline verifies AOT compatibility on every build.

Contributing

Please see CONTRIBUTING.md for guidelines.

License

See the LICENSE file for details.

About

A fast, opinionated C# code generator for OpenAPI specifications. Generates records, enums, and type aliases from OpenAPI 3.x schemas.

Topics

Resources

Contributing

Stars

1 star

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages