OpenApiExamples 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package OpenApiExamples --version 1.1.0
                    
NuGet\Install-Package OpenApiExamples -Version 1.1.0
                    
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="OpenApiExamples" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OpenApiExamples" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="OpenApiExamples" />
                    
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 OpenApiExamples --version 1.1.0
                    
#r "nuget: OpenApiExamples, 1.1.0"
                    
#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 OpenApiExamples@1.1.0
                    
#: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=OpenApiExamples&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=OpenApiExamples&version=1.1.0
                    
Install as a Cake Tool

OpenApiExamples

Make your API docs actually useful. Real request and response examples in your OpenAPI document, with zero boilerplate.

NuGet Downloads License: MIT

OpenAPI examples for ASP.NET Core minimal APIs on .NET 10, rendered by Swagger UI and Scalar.


Why OpenApiExamples?

  • ✨ Rich, realistic examples in seconds
  • ⚡ Zero runtime cost, examples are written when the document is generated
  • 🧩 Seamless ASP.NET Core integration, no extra middleware
  • 🎯 One example or many named ones, per endpoint or per route group
  • 📄 JSON and XML built in, anything else through your own formatter
  • 💉 First-class dependency injection support

Your OpenAPI docs deserve better than empty schemas. ASP.NET Core generates the shape of your payloads but never the content, so your consumers get a Widget with no widget in it. OpenApiExamples fills that in.

Install

Install-Package OpenApiExamples
dotnet add package OpenApiExamples

Get started in three steps

1. Register the services and the transformers.

using OpenApiExamples.ExtensionMethods;

var builder = WebApplication.CreateBuilder(args);

// JsonSerializerDefaults.Web makes examples camelCase, matching the schemas ASP.NET Core generates.
// See Configuration below for why this matters.
builder.Services.AddOpenApiExamples(options =>
    options.JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web));

builder.Services.AddOpenApi(options => options.AddExamples());

var app = builder.Build();
app.MapOpenApi();

2. Write a provider. A plain class that returns your example. No registration needed.

using OpenApiExamples;
using OpenApiExamples.Abstractions;

public class CreateWidgetExample : ISingleOpenApiExamplesProvider<Widget>
{
    public IOpenApiExample<Widget> GetExample() =>
        OpenApiExample.Create("default", new Widget { Id = 1, Name = "Blue Widget" });
}

3. Attach it to an endpoint.

app.MapPost("/widgets", (Widget widget) => TypedResults.Ok(widget))
    .RequestExample<CreateWidgetExample>("application/json")
    .ResponseExample<CreateWidgetExample>(200, "application/json");

That's it. Your document now carries the example inline, and Swagger UI pre-fills its "try it out" box with it:

"requestBody": {
  "content": {
    "application/json": {
      "schema": { "$ref": "#/components/schemas/Widget" },
      "example": { "id": 1, "name": "Blue Widget" }
    }
  }
}

Multiple named examples

Give your consumers a dropdown. Implement IMultipleOpenApiExamplesProvider<TModel> and every example gets a key, a summary and a description:

public class WidgetExamples : IMultipleOpenApiExamplesProvider<Widget>
{
    public IEnumerable<IOpenApiExample<Widget>> GetExamples() =>
    [
        OpenApiExample.Create("small", "A small widget", new Widget { Id = 1, Name = "Bolt" }),
        OpenApiExample.Create(
            key: "large",
            summary: "A large widget",
            description: "Takes two people to lift.",
            value: new Widget { Id = 2, Name = "Girder" }
        ),
    ];
}

Attach it with the plural methods:

app.MapGet("/widgets", () => TypedResults.Ok(widgets))
    .ResponseExamples<WidgetExamples>(200, "application/json");

OpenApiExample.Create has three overloads: key and value, plus optional summary and description, and whichever you fill in are carried into the document.

Route group examples

Declare a shared error shape once and every endpoint in the group picks it up:

var api = app.MapGroup("/api")
    .ResponseExample<ProblemDetailsExample>(400, "application/problem+json");

api.MapGet("/widgets", () => TypedResults.Ok(widgets));
api.MapGet("/gadgets", () => TypedResults.Ok(gadgets));

Request examples are per endpoint, since a group has no single request body.

API reference

Method Applies to Provider interface
RequestExample<T>(contentType) endpoint ISingleOpenApiExamplesProvider
RequestExamples<T>(contentType) endpoint IMultipleOpenApiExamplesProvider
ResponseExample<T>(statusCode, contentType) endpoint, group ISingleOpenApiExamplesProvider
ResponseExamples<T>(statusCode, contentType) endpoint, group IMultipleOpenApiExamplesProvider

ResponseExample and ResponseExamples both accept the status code as either an int or a string.

Supported content types

Content type Written as
application/json JSON object, array or value
application/problem+json JSON object, array or value
application/xml string containing the serialized XML
text/xml string containing the serialized XML

XML comes out as a string rather than a nested structure. That is the specification, not a bug: the document you are writing into is itself JSON, so the XML payload lives in it as a string value.

Note An example is only written if the operation actually declares that content type. When you use a content type the endpoint does not produce by default, declare it as well:

app.MapGet("/widgets/{id}", (int id) => TypedResults.Ok(widget))
    .Produces<Widget>(200, "application/xml")
    .ResponseExample<WidgetExample>(200, "application/xml");

Configuration

builder.Services.AddOpenApiExamples(options =>
{
    options.JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
    options.XmlSerializerOptions.Encoding = Encoding.UTF8;
});
Option Purpose
JsonSerializerOptions Controls how examples are serialized for JSON content types
XmlSerializerOptions.Encoding Encoding declared in the generated XML
Formatters The content type to formatter map, keyed by content type

Why does my example not match my schema?

Almost always the casing. JsonSerializerOptions defaults to new JsonSerializerOptions(), which keeps your property names exactly as written, while ASP.NET Core generates camelCase schemas. If your models are PascalCase your examples will quietly disagree with your own schemas, and nothing tells you until a spec validator does. Passing new JsonSerializerOptions(JsonSerializerDefaults.Web) lines the two up.

Dependency injection

Providers are constructed through ActivatorUtilities, so they take constructor dependencies like anything else in your application, and you still never register them yourself:

public class WidgetExample : ISingleOpenApiExamplesProvider<Widget>
{
    private readonly IWidgetCatalog catalog;

    public WidgetExample(IWidgetCatalog catalog) => this.catalog = catalog;

    public IOpenApiExample<Widget> GetExample() =>
        OpenApiExample.Create("default", this.catalog.Featured);
}

Custom formatters

Need a content type that is not in the table? Write a formatter:

using System.Text.Json.Nodes;
using OpenApiExamples.Abstractions;

public class YamlExamplesFormatter : IOpenApiExamplesFormatter
{
    public IEnumerable<string> SupportedContentTypes => ["application/yaml"];

    public ValueTask<JsonNode> FormatAsync(object example)
    {
        var yaml = MyYamlSerializer.Serialize(example);
        return ValueTask.FromResult<JsonNode>(JsonValue.Create(yaml)!);
    }
}

Register it after AddOpenApiExamples:

builder.Services
    .AddOpenApiExamples()
    .AddExamplesFormatter<YamlExamplesFormatter>();

Claiming a content type that is already mapped replaces the existing formatter and logs a warning, which is how you override the built-in JSON or XML behaviour. Registering the same formatter type twice throws.

Scope

This is a minimal API library and it stays one. Examples are written at document-generation time, so a provider that reaches for a database does that work at startup rather than per request.

Requirements

  • .NET 10
  • Microsoft.AspNetCore.OpenApi, ASP.NET Core's built-in OpenAPI document generation

License

MIT © Chris Mavrommatis

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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
1.2.0 165 8/31/2026
1.1.0 107 8/29/2026
1.0.2 863 7/28/2026
1.0.1 2,410 11/26/2025
1.0.0 320 11/26/2025 1.0.0 is deprecated because it has critical bugs.
0.0.3 501 8/26/2025
0.0.2 258 5/18/2025
0.0.1 460 5/16/2025