Skip to content

vitalybibikov/AzureExtensions.Swashbuckle

Repository files navigation

AzureExtensions.Swashbuckle

Swagger and Swagger UI for Azure Functions (isolated worker model) powered by Swashbuckle. Supports OpenAPI 2.0, 3.0, and 3.1.

CI Auto-Release NuGet NuGet Downloads License: MIT

.NET 8 .NET 9 Swashbuckle 10 Swagger UI OpenAPI Azure Functions Tests


What's New in v5.0.5

  • Fixed ConfigureFunctionsWebApplication compatibility — removed AddMvcCore() which registered the full MVC routing pipeline, conflicting with Azure Functions HTTP routing and causing requests to hang
  • New Integration test CI workflow — validates all Swagger endpoints on both Linux and Windows via func start
  • Cleaned up TestFunction SwaggerController (removed diagnostic logging)

What's New in v5.0.4

  • New IActionResult-based extension methods for ConfigureFunctionsWebApplication
    • CreateSwaggerJsonDocumentResult, CreateSwaggerYamlDocumentResult, CreateSwaggerUIResult, CreateSwaggerOAuth2RedirectResult
    • Uses ContentResult — no HttpResponseData pipeline issues
  • New SwaggerValidate self-test endpoint in TestFunction
  • Fixed startup crash (0x80008096) caused by missing MVC core service registrations
  • Added test fakes (FakeHttpRequestData, FakeHttpResponseData) for extension method testing
  • Added 55 new tests: 25 HttpResponseData extension + 16 IActionResult extension + 14 DI functional (191 total)

What's New in v5.0.1

  • Updated embedded Swagger UI from v5.11 to v5.32.0
  • Fixed resource leaks in response extension methods
  • Fixed route parameter regex matching bug
  • Fixed FunctionContext incorrectly treated as body parameter (#122)
  • Fixed XML documentation file not found in TFM subdirectories (#114)
  • Fixed Content-Type header on JSON/YAML responses (#119)
  • Added IDisposable to SwashbuckleConfig for proper cleanup
  • Added 136 unit, integration, and end-to-end tests

Features

  • Isolated Worker Model — Built for Azure Functions v4 isolated worker (the recommended model going forward)
  • Swashbuckle 10.x — Latest Swashbuckle.AspNetCore with Microsoft.OpenApi v2 support
  • OpenAPI 2.0 / 3.0 / 3.1 — Generate specs in any supported version
  • Swagger UI — Embedded Swagger UI served directly from your Azure Function
  • Multi-document — Define multiple API versions/documents
  • XML Comments — Automatic parameter and response documentation from XML docs
  • Custom Attributes[QueryStringParameter], [RequestHttpHeader], [SwaggerUploadFile], [RequestBodyType]
  • OAuth2 Support — Built-in OAuth2 redirect endpoint and client configuration
  • Newtonsoft.Json — Optional Newtonsoft serialization support
  • Multi-targeting — .NET 8.0 (LTS) and .NET 9.0 (STS)

Installation

dotnet add package AzureExtensions.Swashbuckle

Quick Start

1. Register the Extension in Program.cs

using AzureFunctions.Extensions.Swashbuckle;
using AzureFunctions.Extensions.Swashbuckle.Settings;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureServices((hostContext, services) =>
    {
        services.AddSwashBuckle(opts =>
        {
            opts.RoutePrefix = "api";
            opts.SpecVersion = OpenApiSpecVersion.OpenApi3_0;
            opts.AddCodeParameter = true;
            opts.PrependOperationWithRoutePrefix = true;
            opts.XmlPath = "MyFunctionApp.xml";
            opts.Documents = new[]
            {
                new SwaggerDocument
                {
                    Name = "v1",
                    Title = "My API",
                    Description = "My Azure Functions API",
                    Version = "v1"
                }
            };
            opts.Title = "My API";
        });
    })
    .Build();

host.Run();

Note: AddSwashBuckle is fully compatible with ConfigureFunctionsWebApplication (ASP.NET Core integration). It does not register AddMvcCore() — only the minimal services needed for API description, so it won't interfere with Azure Functions HTTP routing.

2. Add Swagger Endpoints

Recommended — use IActionResult with ConfigureFunctionsWebApplication:

public class SwaggerController
{
    private readonly ISwashBuckleClient swashBuckleClient;

    public SwaggerController(ISwashBuckleClient swashBuckleClient)
    {
        this.swashBuckleClient = swashBuckleClient;
    }

    [SwaggerIgnore]
    [Function("SwaggerJson")]
    public async Task<IActionResult> SwaggerJson(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Swagger/json")]
        HttpRequest req)
    {
        return await this.swashBuckleClient.CreateSwaggerJsonDocumentResult(req);
    }

    [SwaggerIgnore]
    [Function("SwaggerYaml")]
    public async Task<IActionResult> SwaggerYaml(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Swagger/yaml")]
        HttpRequest req)
    {
        return await this.swashBuckleClient.CreateSwaggerYamlDocumentResult(req);
    }

    [SwaggerIgnore]
    [Function("SwaggerUi")]
    public async Task<IActionResult> SwaggerUi(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Swagger/ui")]
        HttpRequest req)
    {
        return await this.swashBuckleClient.CreateSwaggerUIResult(req, "swagger/json");
    }
}

3. Open Swagger UI

Navigate to https://your-function-app/api/swagger/ui in your browser.


Configuration Options

XML Documentation

Enable XML doc generation in your .csproj:

<PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

Then pass the XML path:

opts.XmlPath = "MyFunctionApp.xml";

Multiple Documents

opts.Documents = new[]
{
    new SwaggerDocument { Name = "v1", Title = "API v1", Version = "v1" },
    new SwaggerDocument { Name = "v2", Title = "API v2", Version = "v2" }
};

OAuth2

opts.ConfigureSwaggerGen = x =>
{
    x.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
    {
        Type = SecuritySchemeType.OAuth2,
        Flows = new OpenApiOAuthFlows
        {
            Implicit = new OpenApiOAuthFlow
            {
                AuthorizationUrl = new Uri("https://your.idserver.net/connect/authorize"),
                Scopes = new Dictionary<string, string>
                {
                    { "api.read", "Access read operations" },
                    { "api.write", "Access write operations" }
                }
            }
        }
    });
};

opts.ClientId = "your.client.id";
opts.OAuth2RedirectPath = "http://localhost:7071/api/swagger/oauth2-redirect";

Custom Attributes

// Add query string parameters
[QueryStringParameter("page", "Page number", DataType = typeof(int), Required = false)]
[Function("GetItems")]
public async Task<HttpResponseData> GetItems(...)

// Add required HTTP headers
[RequestHttpHeader("X-Api-Key", isRequired: true)]
[Function("SecureEndpoint")]
public async Task<HttpResponseData> SecureEndpoint(...)

// File upload
[SwaggerUploadFile("file", "File to upload")]
[Function("Upload")]
public async Task<HttpResponseData> Upload(...)

Newtonsoft.Json Support

services.AddSwashBuckle(opts =>
{
    opts.AddNewtonsoftSupport = true;
    // ...
});

Migration from v4.x to v5.x

v5.0 includes breaking changes due to the Swashbuckle 10.x / Microsoft.OpenApi v2 upgrade:

Change v4.x v5.x
Swagger document methods Synchronous Async (GetSwaggerJsonDocumentAsync)
OpenAPI schema types Type = "string" Type = JsonSchemaType.String
Nullable schemas Nullable = true JsonSchemaType.X | JsonSchemaType.Null
OpenAPI namespace Microsoft.OpenApi.Models Microsoft.OpenApi

Async Document Methods

// v4.x
Stream json = client.GetSwaggerJsonDocument(req, "v1");

// v5.x
Stream json = await client.GetSwaggerJsonDocumentAsync(req, "v1");

Sample Project

See the TestFunction project for a complete working example.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

Copyright © 2026, Vitali Bibikov. Code released under the MIT License.

Packages

 
 
 

Contributors