Indiko.Blocks.API.Swagger 2.1.2

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

Indiko.Blocks.API.Swagger

Swagger/OpenAPI documentation block for generating interactive API documentation with authentication support and API versioning.

Overview

This package provides automatic Swagger/OpenAPI documentation generation for ASP.NET Core Web APIs, with built-in support for JWT Bearer authentication, API versioning, XML documentation, and custom filters.

Features

  • Swagger UI: Interactive API documentation and testing interface
  • OpenAPI 3.0: Standard OpenAPI specification generation
  • API Versioning: Automatic versioning support with URL segments
  • JWT Authentication: Built-in Bearer token authentication UI
  • XML Documentation: Automatic XML comment inclusion
  • Custom Filters: Operation filters for enhanced documentation
  • Deep Linking: Direct links to specific API operations
  • Deprecated APIs: Visual indicators for deprecated endpoints
  • Response Examples: Support for request/response examples
  • Auto-Discovery: Automatic endpoint discovery

Installation

dotnet add package Indiko.Blocks.API.Swagger

Quick Start

Enable Swagger Block

using Indiko.Hosting.Web;

public class Startup : WebStartup
{
    public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        : base(configuration, environment)
    {
    }

    protected override bool AddControllersWithViews => false;
    protected override bool EnableForwardedHeaderOptions => false;
    protected override bool ForceHttps => true;
    
    // Swagger is automatically enabled via block system
}

Configuration (appsettings.json)

{
  "SwaggerOptions": {
    "Enabled": true,
    "Title": "My API",
    "Description": "RESTful API for My Application",
    "ApiPrefix": "api",
    "TermsOfService": "https://example.com/terms",
    "Contact": {
      "Name": "API Support",
      "Email": "support@example.com",
      "Url": "https://example.com/support"
    },
    "License": {
      "Name": "MIT",
      "Url": "https://opensource.org/licenses/MIT"
    }
  }
}

Access Swagger UI

Once configured, Swagger UI is available at:

https://localhost:5001/

Or specifically:

https://localhost:5001/swagger

API Versioning

Define Versioned Controllers

using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class UsersController : ControllerBase
{
    /// <summary>
    /// Gets all users
    /// </summary>
    /// <returns>List of users</returns>
    /// <response code="200">Returns the list of users</response>
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<IActionResult> GetUsers()
    {
        // Implementation
        return Ok(users);
    }
    
    /// <summary>
    /// Gets a specific user by ID
    /// </summary>
    /// <param name="id">User ID</param>
    /// <returns>User details</returns>
    /// <response code="200">Returns the user</response>
    /// <response code="404">User not found</response>
    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetUser(Guid id)
    {
        // Implementation
        return Ok(user);
    }
}

Multiple API Versions

// Version 1.0
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0")]
public class UsersV1Controller : ControllerBase
{
    [HttpGet]
    public IActionResult GetUsers()
    {
        // V1 implementation
        return Ok(usersV1);
    }
}

// Version 2.0
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("2.0")]
public class UsersV2Controller : ControllerBase
{
    [HttpGet]
    public IActionResult GetUsers()
    {
        // V2 implementation with more features
        return Ok(usersV2);
    }
}

// Deprecated version
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiVersion("1.0", Deprecated = true)]
public class OrdersV1Controller : ControllerBase
{
    [HttpGet]
    public IActionResult GetOrders()
    {
        // Old implementation
        return Ok(orders);
    }
}

XML Documentation

Enable XML Documentation in Project

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn> 
  </PropertyGroup>
</Project>

Document Your APIs

/// <summary>
/// User management controller
/// </summary>
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class UsersController : ControllerBase
{
    /// <summary>
    /// Creates a new user
    /// </summary>
    /// <param name="command">User creation data</param>
    /// <returns>Created user ID</returns>
    /// <remarks>
    /// Sample request:
    /// 
    ///     POST /api/v1/users
    ///     {
    ///        "firstName": "John",
    ///        "lastName": "Doe",
    ///        "email": "john.doe@example.com"
    ///     }
    /// 
    /// </remarks>
    /// <response code="201">User created successfully</response>
    /// <response code="400">Invalid request data</response>
    /// <response code="409">Email already exists</response>
    [HttpPost]
    [ProducesResponseType(typeof(Guid), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status409Conflict)]
    public async Task<IActionResult> CreateUser([FromBody] CreateUserCommand command)
    {
        var userId = await _mediator.Send<CreateUserCommand, Guid>(command);
        return CreatedAtAction(nameof(GetUser), new { id = userId }, userId);
    }
}

Authentication Documentation

JWT Bearer Authentication

The Swagger UI includes built-in JWT Bearer token authentication:

  1. Click the "Authorize" button at the top right
  2. Enter your token in the format: Bearer {your-token}
  3. Click "Authorize"
  4. All subsequent requests include the token

Require Authentication

using Microsoft.AspNetCore.Authorization;

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[Authorize] // Requires authentication for all actions
public class SecureController : ControllerBase
{
    [HttpGet]
    public IActionResult GetSecureData()
    {
        return Ok(secureData);
    }
    
    [HttpPost]
    [AllowAnonymous] // Allow anonymous access to specific action
    public IActionResult PublicEndpoint()
    {
        return Ok("Public data");
    }
}

Custom Attributes

Implementation Notes

using Indiko.Blocks.API.Swagger.Attributes;

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet]
    [ImplementationNotes("This endpoint returns a cached list of products. Cache expires after 5 minutes.")]
    public IActionResult GetProducts()
    {
        return Ok(products);
    }
}

Request/Response Examples

Using Swashbuckle Annotations

using Swashbuckle.AspNetCore.Annotations;

public class CreateUserCommand
{
    /// <example>John</example>
    public string FirstName { get; set; }
    
    /// <example>Doe</example>
    public string LastName { get; set; }
    
    /// <example>john.doe@example.com</example>
    public string Email { get; set; }
}

[HttpPost]
[SwaggerOperation(
    Summary = "Creates a new user",
    Description = "Creates a new user account with the provided information",
    OperationId = "CreateUser",
    Tags = new[] { "Users" }
)]
[SwaggerResponse(201, "User created successfully", typeof(Guid))]
[SwaggerResponse(400, "Invalid request data")]
[SwaggerResponse(409, "Email already exists")]
public async Task<IActionResult> CreateUser([FromBody] CreateUserCommand command)
{
    var userId = await _mediator.Send<CreateUserCommand, Guid>(command);
    return CreatedAtAction(nameof(GetUser), new { id = userId }, userId);
}

Custom Operation Filters

The block includes several built-in filters:

AddBearerAuthHeaderOperationFilter

Adds Bearer token authentication to operations with [Authorize] attribute.

AuthenticationResponseCodesOperationFilter

Automatically adds 401 (Unauthorized) and 403 (Forbidden) response codes to secured endpoints.

ImplementationNotesAttributeFilter

Processes [ImplementationNotes] attribute and adds notes to Swagger documentation.

LowercaseDocumentsFilter

Converts all URLs to lowercase in the Swagger documentation.

Advanced Configuration

Custom Swagger Options

public class CustomSwaggerBlock : SwaggerBlock
{
    public CustomSwaggerBlock(IConfiguration configuration, ILogger logger) 
        : base(configuration, logger)
    {
    }

    public override void ConfigureServices(IServiceCollection services)
    {
        base.ConfigureServices(services);
        
        // Add custom filters
        services.Configure<SwaggerGenOptions>(options =>
        {
            options.OperationFilter<MyCustomOperationFilter>();
            options.DocumentFilter<MyCustomDocumentFilter>();
        });
    }
}

Group by Tags

[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
[Tags("User Management")]
public class UsersController : ControllerBase
{
    // All endpoints grouped under "User Management"
}

Security Schemes

OAuth2 Configuration

services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("OAuth2", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Flows = new OpenApiOAuthFlows
        {
            AuthorizationCode = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new Uri("https://identity.example.com/connect/authorize"),
                TokenUrl = new Uri("https://identity.example.com/connect/token"),
                Scopes = new Dictionary<string, string>
                {
                    { "api", "API Access" },
                    { "profile", "Profile Access" }
                }
            }
        }
    });
});

File Upload Documentation

/// <summary>
/// Uploads a file
/// </summary>
/// <param name="file">File to upload</param>
[HttpPost("upload")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> UploadFile(IFormFile file)
{
    // Implementation
    return Ok(new { FileName = file.FileName, Size = file.Length });
}

Enum Documentation

/// <summary>
/// User status
/// </summary>
public enum UserStatus
{
    /// <summary>User is active</summary>
    Active = 0,
    
    /// <summary>User is inactive</summary>
    Inactive = 1,
    
    /// <summary>User is suspended</summary>
    Suspended = 2
}

Best Practices

  1. Always Add XML Comments: Document all public APIs with XML comments
  2. Use ProducesResponseType: Specify all possible response types
  3. Version Your APIs: Use semantic versioning (v1.0, v2.0)
  4. Group Related Endpoints: Use Tags to organize endpoints
  5. Example Values: Provide example values for properties
  6. Deprecation: Mark deprecated endpoints clearly
  7. Security: Document authentication requirements
  8. Error Responses: Document all possible error scenarios

Swagger UI Features

  • Try it out: Test endpoints directly from the browser
  • Model Schemas: View request/response models
  • Authorization: Test authenticated endpoints
  • Download Spec: Download OpenAPI specification (JSON/YAML)
  • Deep Linking: Share links to specific endpoints
  • Code Generation: Generate client code

Production Considerations

Disable in Production

public override void Configure(IApplicationBuilder app, IServiceProvider serviceProvider, IHostEnvironment environment)
{
    if (environment.IsDevelopment())
    {
        base.Configure(app, serviceProvider, environment);
    }
}

Or with Configuration

{
  "SwaggerOptions": {
    "Enabled": false  // Disable in production
  }
}

URL Routing

Swagger UI is available at multiple URLs:

  • / - Root (default)
  • /swagger - Explicit Swagger path
  • /swagger/v1/swagger.json - OpenAPI spec for v1
  • /swagger/v2/swagger.json - OpenAPI spec for v2

Target Framework

  • .NET 10

Dependencies

  • Swashbuckle.AspNetCore (6.5+)
  • Swashbuckle.AspNetCore.Filters
  • Swashbuckle.AspNetCore.Annotations
  • Asp.Versioning.Mvc.ApiExplorer
  • Indiko.Blocks.Common.Abstractions

License

See LICENSE file in the repository root.

  • Indiko.Blocks.API.Compression - Response compression
  • Indiko.Blocks.API.FeatureManagement - Feature flags
  • Indiko.Blocks.API.Idempotency - Idempotent requests
  • Indiko.Blocks.Security.Authentication.ASPNetCore - Authentication

Resources

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
2.1.2 268 12/18/2025
2.1.1 668 12/2/2025
2.1.0 665 12/2/2025
2.0.0 273 9/17/2025
1.7.23 193 9/8/2025
1.7.22 178 9/8/2025
1.7.21 188 8/14/2025
1.7.20 191 6/23/2025
1.7.19 223 6/3/2025
1.7.18 194 5/29/2025
1.7.17 215 5/26/2025
1.7.15 162 4/12/2025
1.7.14 184 4/11/2025
1.7.13 184 3/29/2025
1.7.12 170 3/28/2025
1.7.11 205 3/28/2025
1.7.10 175 3/28/2025
1.7.9 173 3/28/2025
1.7.8 181 3/28/2025
1.7.5 218 3/17/2025
1.7.4 187 3/16/2025
1.7.3 175 3/16/2025
1.7.2 196 3/16/2025
1.7.1 212 3/11/2025
1.7.0 215 3/11/2025
1.6.8 244 3/11/2025
1.6.7 282 3/4/2025
1.6.6 151 2/26/2025
1.6.5 149 2/20/2025
1.6.4 147 2/20/2025
1.6.3 154 2/5/2025
1.6.2 149 1/24/2025
1.6.1 174 1/24/2025
1.6.0 179 1/16/2025
1.5.2 135 1/16/2025
1.5.1 183 11/3/2024
1.5.0 158 10/26/2024
1.3.2 178 10/24/2024
1.3.0 174 10/10/2024
1.2.5 166 10/9/2024
1.2.4 183 10/8/2024
1.2.1 151 10/3/2024
1.2.0 178 9/29/2024
1.1.1 175 9/23/2024
1.1.0 194 9/18/2024
1.0.33 194 9/15/2024
1.0.28 196 8/28/2024
1.0.27 206 8/24/2024
1.0.26 186 7/7/2024
1.0.25 177 7/6/2024
1.0.24 182 6/25/2024
1.0.23 186 6/1/2024
1.0.22 192 5/14/2024
1.0.21 179 5/14/2024
1.0.20 210 4/8/2024
1.0.19 204 4/3/2024
1.0.18 209 3/23/2024
1.0.17 203 3/19/2024
1.0.16 203 3/19/2024
1.0.15 203 3/11/2024
1.0.14 210 3/10/2024
1.0.13 188 3/6/2024
1.0.12 197 3/1/2024
1.0.11 199 3/1/2024
1.0.10 176 3/1/2024
1.0.9 205 3/1/2024
1.0.8 185 2/19/2024
1.0.7 203 2/17/2024
1.0.6 173 2/17/2024
1.0.5 163 2/17/2024
1.0.4 198 2/7/2024
1.0.3 169 2/6/2024
1.0.1 195 2/6/2024
1.0.0 237 1/9/2024
1.0.0-preview99 227 12/22/2023
1.0.0-preview98 184 12/21/2023
1.0.0-preview97 164 12/21/2023
1.0.0-preview96 203 12/20/2023
1.0.0-preview94 147 12/18/2023
1.0.0-preview93 357 12/13/2023
1.0.0-preview92 162 12/13/2023
1.0.0-preview91 219 12/12/2023
1.0.0-preview90 182 12/11/2023
1.0.0-preview89 199 12/11/2023
1.0.0-preview88 286 12/6/2023
1.0.0-preview87 189 12/6/2023
1.0.0-preview86 180 12/6/2023
1.0.0-preview85 173 12/6/2023
1.0.0-preview84 190 12/5/2023
1.0.0-preview83 264 12/5/2023
1.0.0-preview82 200 12/5/2023
1.0.0-preview81 195 12/4/2023
1.0.0-preview80 167 12/1/2023
1.0.0-preview77 190 12/1/2023
1.0.0-preview76 180 12/1/2023
1.0.0-preview75 180 12/1/2023
1.0.0-preview74 204 11/26/2023
1.0.0-preview73 207 11/7/2023
1.0.0-preview72 167 11/6/2023
1.0.0-preview71 194 11/3/2023
1.0.0-preview70 194 11/2/2023
1.0.0-preview69 142 11/2/2023
1.0.0-preview68 166 11/2/2023
1.0.0-preview67 173 11/2/2023
1.0.0-preview66 138 11/2/2023
1.0.0-preview65 200 11/2/2023
1.0.0-preview64 172 11/2/2023
1.0.0-preview63 173 11/2/2023
1.0.0-preview62 200 11/1/2023
1.0.0-preview61 171 11/1/2023
1.0.0-preview60 169 11/1/2023
1.0.0-preview59 162 11/1/2023
1.0.0-preview58 177 10/31/2023
1.0.0-preview57 173 10/31/2023
1.0.0-preview56 165 10/31/2023
1.0.0-preview55 182 10/31/2023
1.0.0-preview54 147 10/31/2023
1.0.0-preview53 144 10/31/2023
1.0.0-preview52 146 10/31/2023
1.0.0-preview51 166 10/31/2023
1.0.0-preview50 183 10/31/2023
1.0.0-preview48 154 10/31/2023
1.0.0-preview46 178 10/31/2023
1.0.0-preview45 186 10/31/2023
1.0.0-preview44 165 10/31/2023
1.0.0-preview43 155 10/31/2023
1.0.0-preview42 141 10/30/2023
1.0.0-preview41 170 10/30/2023
1.0.0-preview40 168 10/27/2023
1.0.0-preview39 185 10/27/2023
1.0.0-preview38 160 10/27/2023
1.0.0-preview37 194 10/27/2023
1.0.0-preview36 151 10/27/2023
1.0.0-preview35 161 10/27/2023
1.0.0-preview34 146 10/27/2023
1.0.0-preview33 178 10/26/2023
1.0.0-preview32 171 10/26/2023
1.0.0-preview31 189 10/26/2023
1.0.0-preview30 177 10/26/2023
1.0.0-preview29 178 10/26/2023
1.0.0-preview28 162 10/26/2023
1.0.0-preview27 194 10/26/2023
1.0.0-preview26 175 10/25/2023
1.0.0-preview25 226 10/23/2023
1.0.0-preview24 199 10/23/2023
1.0.0-preview23 166 10/23/2023
1.0.0-preview22 181 10/23/2023
1.0.0-preview21 164 10/23/2023
1.0.0-preview20 181 10/20/2023
1.0.0-preview19 187 10/19/2023
1.0.0-preview18 183 10/18/2023
1.0.0-preview16 222 10/11/2023
1.0.0-preview14 211 10/10/2023
1.0.0-preview13 178 10/10/2023
1.0.0-preview12 169 10/9/2023
1.0.0-preview11 186 10/9/2023
1.0.0-preview101 150 1/5/2024