Folio.AspNetCore 1.3.0

dotnet add package Folio.AspNetCore --version 1.3.0
                    
NuGet\Install-Package Folio.AspNetCore -Version 1.3.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="Folio.AspNetCore" Version="1.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Folio.AspNetCore" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Folio.AspNetCore" />
                    
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 Folio.AspNetCore --version 1.3.0
                    
#r "nuget: Folio.AspNetCore, 1.3.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 Folio.AspNetCore@1.3.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=Folio.AspNetCore&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Folio.AspNetCore&version=1.3.0
                    
Install as a Cake Tool

Folio.AspNetCore

An embeddable OpenAPI documentation and testing UI for ASP.NET Core, packaged as middleware: no separate infrastructure, no static hosting — just a NuGet package.

Folio in action

Screenshots

Rendered from a sample e-commerce API spec — see docs/demo-openapi.json. Click a thumbnail for the full-size screenshot.

Welcome screen GET endpoint POST endpoint with request body Executed response
Endpoint list & model catalog GET endpoint & response schema Type-aware request body builder Request execution & generated cURL
Model catalog Authorize modal Search Dark mode
Full, searchable model catalog Authorization against security schemes Instant endpoint search Dark mode

Installation

dotnet add package Folio.AspNetCore

See CHANGELOG.md for release history, and the Wiki for full docs (getting started, authorization, FAQ).

Usage

The package doesn't care how you generate your OpenAPI document — it just renders whatever you point it at via SpecUrl. Any source works: the built-in Microsoft.AspNetCore.OpenApi, Swashbuckle, NSwag, or a static file.

With built-in Microsoft.AspNetCore.OpenApi (.NET 9+)

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi(); // publishes /openapi/v1.json

app.UseFolio(options =>
{
    options.RoutePrefix = "docs";           // UI will be at /docs
    options.SpecUrl     = "/openapi/v1.json";
    options.Title       = "My API";          // optional
});

app.Run();

With Swashbuckle

builder.Services.AddSwaggerGen();
// ...
app.UseSwagger(); // publishes /swagger/v1/swagger.json

app.UseFolio(options =>
{
    options.SpecUrl = "/swagger/v1/swagger.json";
});

Open /docs (or your configured RoutePrefix) — you'll see the endpoint list, model schemas, a type-aware request builder, in-browser request execution with generated cURL, environment support, and authorization against the spec's security schemes (apiKey, HTTP Bearer/Basic).

Options (FolioOptions)

Property Default Description
RoutePrefix "folio" Path the UI is served under (no leading/trailing slashes).
SpecUrl "/openapi/v1.json" URL of the OpenAPI document — required for a real project.
Title null Page/header title. Falls back to the spec's info.title if not set.
AuthorizationPolicy null Name of an ASP.NET Core authorization policy the UI is gated behind. See Authorization.
LogoutUrl null Shows a "Log out" button in the header, pointing here. Hidden if unset.
ShowTryItOut true Shows the "Send request" button that executes real requests against your API.
ShowRoles true Shows the role badges/popover read from your endpoints' own [Authorize(Roles = "...")].
ShowCodeGenerator true Shows the multi-language code generator (cURL/JS/Python/C#/Go/PowerShell) in the request panel.
ShowSchema true Shows the Schema button for viewing a model's JSON schema.
ShowHome true Shows the "Home" button (returns to the welcome screen).
ShowEnvironmentSwitcher true Shows the environment/base-URL switcher (add/edit environments, import servers from the spec).
ShowGlobalHeaders true Shows the "Global headers" button (headers sent with every request).
ShowAuthorize true Shows the OpenAPI security scheme "Authorization" button, when the spec declares one.
ShowExamples true Shows "Save example" / "My examples".
ShowShare true Shows the "Copy endpoint link" button.

Set any of these directly in code:

app.UseFolio(options =>
{
    options.SpecUrl = "/openapi/v1.json";
    options.ShowTryItOut = false;
});

Or bind them from appsettings.json (or any other IConfiguration source) — Folio never reads configuration on its own, so this only happens if you call it explicitly, the same way Serilog's ReadFrom.Configuration(...) works:

{
  "Folio": {
    "ShowTryItOut": false,
    "ShowCodeGenerator": false
  }
}
app.UseFolio((context, options) =>
{
    options.SpecUrl = "/openapi/v1.json";
    options.ReadFrom.Configuration(context.Configuration, "Folio");
});

Authorization

By default the UI is open to anyone who can reach the route. Two ways to gate it:

You already have auth in your app (cookie, JWT bearer, ASP.NET Core Identity, an external provider, ...) — point AuthorizationPolicy at a policy name and Folio integrates with it the same way a normal [Authorize] endpoint would:

builder.Services.AddAuthorization(options =>
    options.AddPolicy("FolioAccess", policy => policy.RequireAuthenticatedUser()));

app.UseAuthentication();
app.UseAuthorization();

app.UseFolio(options =>
{
    options.SpecUrl = "/openapi/v1.json";
    options.AuthorizationPolicy = "FolioAccess";
    options.LogoutUrl = "/account/logout"; // wherever your app signs out
});

Note: this only gates the Folio UI itself — it doesn't protect the underlying OpenAPI document or your actual API endpoints. Protect those the same way you'd protect any other endpoint.

You have no auth system yet and just want to put a login in front of the docs — AddFolioAuth/UseFolioAuth is a self-contained alternative: give it a list of users and it handles cookie issuance, a login page (styled to match Folio's own dark theme), and the login/logout routes, wiring itself into UseFolio(...) automatically:

builder.Services.AddFolioAuth(options =>
{
    options.Users = builder.Configuration.GetSection("Users").Get<List<FolioUser>>() ?? [];
});

var app = builder.Build();

app.UseFolioAuth();
app.UseFolio(options => options.SpecUrl = "/openapi/v1.json");
// appsettings.json
{
  "Users": [
    { "Username": "admin", "Password": "correct-horse-battery-staple" }
  ]
}

How it works

The UI (HTML/CSS/JS) is embedded into the package assembly as embedded resources and served through the standard StaticFileMiddleware on top of a ManifestEmbeddedFileProvider — with proper ETag/Last-Modified/ conditional requests, not hand-rolled file serving. index.html is served by a small dedicated handler that injects configuration (SpecUrl, Title) into a <script> tag on the fly before the rest of the scripts load — the UI itself hardcodes nothing and works with whatever OpenAPI document you point it at.

The package's static assets live in this repo under assets/ui/ so everything embedded in the published package is visible right here — nothing is pulled in from an external source at build time.

Requirements

  • ASP.NET Core, .NET 6, 7, 8, or 9.
  • No internet connection required at all: fonts, Tailwind CSS, marked.js, and flatpickr are all bundled locally and embedded into the package assembly along with the rest of the UI — zero external requests, both at build time and in the user's browser.
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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 is compatible.  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
1.3.0 65 11/6/2026
1.2.0 126 9/30/2026
1.1.0 116 9/13/2026
1.0.4 119 9/13/2026
1.0.2 143 8/10/2026
1.0.1 124 8/7/2026
1.0.0 126 8/7/2026