Indiko.Blocks.API.Swagger 2.1.1

dotnet add package Indiko.Blocks.API.Swagger --version 2.1.1
                    
NuGet\Install-Package Indiko.Blocks.API.Swagger -Version 2.1.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="Indiko.Blocks.API.Swagger" Version="2.1.1" />
                    
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.1" />
                    
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.1
                    
#r "nuget: Indiko.Blocks.API.Swagger, 2.1.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 Indiko.Blocks.API.Swagger@2.1.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=Indiko.Blocks.API.Swagger&version=2.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Indiko.Blocks.API.Swagger&version=2.1.1
                    
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.1 620 12/2/2025
2.1.0 614 12/2/2025
2.0.0 268 9/17/2025
1.7.23 182 9/8/2025
1.7.22 166 9/8/2025
1.7.21 173 8/14/2025
1.7.20 181 6/23/2025
1.7.19 209 6/3/2025
1.7.18 178 5/29/2025
1.7.17 201 5/26/2025
1.7.15 153 4/12/2025
1.7.14 176 4/11/2025
1.7.13 172 3/29/2025
1.7.12 158 3/28/2025
1.7.11 193 3/28/2025
1.7.10 167 3/28/2025
1.7.9 163 3/28/2025
1.7.8 174 3/28/2025
1.7.5 205 3/17/2025
1.7.4 169 3/16/2025
1.7.3 167 3/16/2025
1.7.2 183 3/16/2025
1.7.1 198 3/11/2025
1.7.0 201 3/11/2025
1.6.8 229 3/11/2025
1.6.7 271 3/4/2025
1.6.6 139 2/26/2025
1.6.5 141 2/20/2025
1.6.4 137 2/20/2025
1.6.3 139 2/5/2025
1.6.2 139 1/24/2025
1.6.1 160 1/24/2025
1.6.0 164 1/16/2025
1.5.2 124 1/16/2025
1.5.1 175 11/3/2024
1.5.0 148 10/26/2024
1.3.2 168 10/24/2024
1.3.0 162 10/10/2024
1.2.5 154 10/9/2024
1.2.4 169 10/8/2024
1.2.1 135 10/3/2024
1.2.0 169 9/29/2024
1.1.1 163 9/23/2024
1.1.0 178 9/18/2024
1.0.33 179 9/15/2024
1.0.28 186 8/28/2024
1.0.27 196 8/24/2024
1.0.26 173 7/7/2024
1.0.25 163 7/6/2024
1.0.24 171 6/25/2024
1.0.23 172 6/1/2024
1.0.22 180 5/14/2024
1.0.21 167 5/14/2024
1.0.20 204 4/8/2024
1.0.19 191 4/3/2024
1.0.18 201 3/23/2024
1.0.17 194 3/19/2024
1.0.16 192 3/19/2024
1.0.15 194 3/11/2024
1.0.14 193 3/10/2024
1.0.13 180 3/6/2024
1.0.12 187 3/1/2024
1.0.11 180 3/1/2024
1.0.10 169 3/1/2024
1.0.9 197 3/1/2024
1.0.8 171 2/19/2024
1.0.7 186 2/17/2024
1.0.6 158 2/17/2024
1.0.5 152 2/17/2024
1.0.4 190 2/7/2024
1.0.3 160 2/6/2024
1.0.1 183 2/6/2024
1.0.0 225 1/9/2024
1.0.0-preview99 215 12/22/2023
1.0.0-preview98 174 12/21/2023
1.0.0-preview97 154 12/21/2023
1.0.0-preview96 190 12/20/2023
1.0.0-preview94 137 12/18/2023
1.0.0-preview93 344 12/13/2023
1.0.0-preview92 154 12/13/2023
1.0.0-preview91 211 12/12/2023
1.0.0-preview90 173 12/11/2023
1.0.0-preview89 189 12/11/2023
1.0.0-preview88 276 12/6/2023
1.0.0-preview87 175 12/6/2023
1.0.0-preview86 169 12/6/2023
1.0.0-preview85 166 12/6/2023
1.0.0-preview84 183 12/5/2023
1.0.0-preview83 251 12/5/2023
1.0.0-preview82 192 12/5/2023
1.0.0-preview81 183 12/4/2023
1.0.0-preview80 159 12/1/2023
1.0.0-preview77 179 12/1/2023
1.0.0-preview76 173 12/1/2023
1.0.0-preview75 169 12/1/2023
1.0.0-preview74 191 11/26/2023
1.0.0-preview73 197 11/7/2023
1.0.0-preview72 157 11/6/2023
1.0.0-preview71 183 11/3/2023
1.0.0-preview70 184 11/2/2023
1.0.0-preview69 133 11/2/2023
1.0.0-preview68 157 11/2/2023
1.0.0-preview67 162 11/2/2023
1.0.0-preview66 130 11/2/2023
1.0.0-preview65 190 11/2/2023
1.0.0-preview64 161 11/2/2023
1.0.0-preview63 161 11/2/2023
1.0.0-preview62 191 11/1/2023
1.0.0-preview61 164 11/1/2023
1.0.0-preview60 155 11/1/2023
1.0.0-preview59 152 11/1/2023
1.0.0-preview58 169 10/31/2023
1.0.0-preview57 165 10/31/2023
1.0.0-preview56 158 10/31/2023
1.0.0-preview55 171 10/31/2023
1.0.0-preview54 140 10/31/2023
1.0.0-preview53 141 10/31/2023
1.0.0-preview52 138 10/31/2023
1.0.0-preview51 160 10/31/2023
1.0.0-preview50 178 10/31/2023
1.0.0-preview48 144 10/31/2023
1.0.0-preview46 168 10/31/2023
1.0.0-preview45 175 10/31/2023
1.0.0-preview44 155 10/31/2023
1.0.0-preview43 149 10/31/2023
1.0.0-preview42 137 10/30/2023
1.0.0-preview41 160 10/30/2023
1.0.0-preview40 159 10/27/2023
1.0.0-preview39 178 10/27/2023
1.0.0-preview38 149 10/27/2023
1.0.0-preview37 185 10/27/2023
1.0.0-preview36 146 10/27/2023
1.0.0-preview35 148 10/27/2023
1.0.0-preview34 138 10/27/2023
1.0.0-preview33 170 10/26/2023
1.0.0-preview32 165 10/26/2023
1.0.0-preview31 178 10/26/2023
1.0.0-preview30 170 10/26/2023
1.0.0-preview29 171 10/26/2023
1.0.0-preview28 153 10/26/2023
1.0.0-preview27 185 10/26/2023
1.0.0-preview26 165 10/25/2023
1.0.0-preview25 220 10/23/2023
1.0.0-preview24 192 10/23/2023
1.0.0-preview23 152 10/23/2023
1.0.0-preview22 172 10/23/2023
1.0.0-preview21 151 10/23/2023
1.0.0-preview20 172 10/20/2023
1.0.0-preview19 180 10/19/2023
1.0.0-preview18 174 10/18/2023
1.0.0-preview16 217 10/11/2023
1.0.0-preview14 202 10/10/2023
1.0.0-preview13 169 10/10/2023
1.0.0-preview12 160 10/9/2023
1.0.0-preview11 178 10/9/2023
1.0.0-preview101 140 1/5/2024