SignalR.OpenApi 1.0.226

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

SignalR.OpenApi

Build NuGet

OpenAPI 3.1 specification generation and SwaggerUI support for ASP.NET Core SignalR hubs.

Features

  • Generates OpenAPI 3.1 specifications from SignalR hub methods
  • Interactive SwaggerUI with SignalR protocol invocation (no HTTP — real SignalR calls)
  • Streaming support: IAsyncEnumerable<T> and ChannelReader<T> with accumulated item history and stream state tracking
  • Client event monitoring: Auto-subscribes to typed hub (Hub<TClient>) events with real-time event log panel
  • Supports standard ASP.NET Core attributes ([Authorize], [Tags], [EndpointSummary], [Obsolete], etc.)
  • XML documentation comments for descriptions and examples
  • [JsonPolymorphic] / [JsonDerivedType] polymorphic schema support with OData-style sub-endpoints
  • Data Annotation validation attributes mapped to OpenAPI schema constraints
  • FluentValidation rules mapped to OpenAPI schema constraints
  • Security scheme detection from [Authorize] / [AllowAnonymous]
  • JWT Bearer token support in SwaggerUI (header or query string)
  • Connection status indicator with automatic reconnection handling
  • Form-urlencoded input mode for primitive and flat object parameters
  • Multiple named request/response examples via custom attributes
  • Embedded @microsoft/signalr bundle (no CDN dependency)
  • Zero proprietary attributes required for core functionality

Getting Started

Installation

dotnet add package SignalR.OpenApi
dotnet add package SignalR.OpenApi.SwaggerUi

Usage

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSignalR();
builder.Services.AddSignalROpenApi();
builder.Services.AddSignalRSwaggerUi();

var app = builder.Build();

app.MapHub<ChatHub>("/hubs/chat");
app.MapSignalROpenApi();
app.UseSignalRSwaggerUi();

app.Run();

The OpenAPI specification is served at /openapi/signalr-v1.json. The SwaggerUI is available at /signalr-swagger.

Configuration

builder.Services.AddSignalROpenApi(options =>
{
    options.DocumentTitle = "My SignalR API";
    options.DocumentVersion = "v1";

    // Include type discriminator in JSON examples for polymorphic sub-endpoints (default: true)
    options.IncludeDiscriminatorInExamples = true;

    // Configure JSON property naming (default: camelCase)
    options.JsonSerializerOptions = new System.Text.Json.JsonSerializerOptions
    {
        PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase,
    };
});

builder.Services.AddSignalRSwaggerUi(options =>
{
    options.RoutePrefix = "signalr-swagger";    // SwaggerUI route (default)
    options.SpecUrl = "/openapi/signalr-v1.json"; // Spec endpoint (default)
    options.DocumentTitle = "SignalR API";       // Browser tab title (default)
    options.StripAsyncSuffix = true;             // Strip "Async" from display names (default)
});

SwaggerUI Features

Method Labels

SignalR operations display custom method labels in SwaggerUI:

Label Description
INVOKE Standard hub method invocation
STREAM Streaming method (IAsyncEnumerable<T> / ChannelReader<T>)
EVENT Client event from typed hub (Hub<TClient>)

Streaming

Streaming operations accumulate items into a growing response array as they arrive. The response shows:

{
  "state": "streaming",
  "count": 5,
  "items": [10, 9, 8, 7, 6]
}

When the stream completes, the state changes to "completed". If an error occurs, it shows "error: ...". A Stop Stream button appears while streaming is active to cancel the subscription.

Client Events

Client events (from Hub<TClient> interface methods) appear as EVENT operations. When you expand one, an event log panel shows:

  • Connection status: Connected / Disconnected indicator
  • Connect & Listen: Button to establish hub connection and start receiving events
  • Event log: Real-time list of received events with timestamps and JSON payloads
  • Clear Log: Button to reset the event history

Events are automatically subscribed when connecting to a hub via any invoke or stream operation.

Request Body Input Modes

Hub methods with parameters support two input modes, selectable via a content-type dropdown in SwaggerUI:

Content Type Input Mode Available When
application/json Raw JSON textarea Always
application/x-www-form-urlencoded Individual form fields Primitive params, single flat objects, polymorphic sub-endpoints

The dropdown appears above the request body when you click Try it out. Form field values are automatically coerced to the correct type (e.g., "5"5 for integers, "true"true for booleans).

Note: Methods with multi-object parameters (two or more complex objects) only support application/json because SwaggerUI cannot render nested objects as form fields.

Polymorphic Parameters

Parameters using [JsonPolymorphic] / [JsonDerivedType] are supported via two mechanisms:

  1. Main endpoint (/hubs/Chat/SendNotification) — uses oneOf with a discriminator for the type selector dropdown in JSON mode.
  2. OData-style sub-endpoints (/hubs/Chat/SendNotification/text, /hubs/Chat/SendNotification/alert) — each derived type gets its own endpoint with a flat schema, supporting both JSON and form-urlencoded input.
[JsonPolymorphic(TypeDiscriminatorPropertyName = "type")]
[JsonDerivedType(typeof(TextNotification), "text")]
[JsonDerivedType(typeof(AlertNotification), "alert")]
public abstract class Notification
{
    public required string Recipient { get; set; }
}

public class TextNotification : Notification
{
    public required string Content { get; set; }
}

public class AlertNotification : Notification
{
    public required string Title { get; set; }
    public required string Severity { get; set; }
}

Note: System.Text.Json polymorphic deserialization requires the type discriminator property to appear first in the JSON object. The SwaggerUI plugin handles this automatically for sub-endpoints.

By default, IncludeDiscriminatorInExamples = true makes the discriminator visible in JSON request examples but hidden in form-urlencoded inputs. Set to false to hide the discriminator from all examples (the plugin still injects it at invocation time).

Supported Attributes

Attribute OpenAPI Mapping
[Tags("group")] tags on operation
[EndpointSummary("...")] summary on operation
[EndpointDescription("...")] description on operation
[EndpointName("Name")] operationId on operation
[Description("...")] description on parameter/property
[Authorize] / [AllowAnonymous] security requirement
[ApiExplorerSettings(IgnoreApi = true)] Excluded from spec
[ExcludeFromDescription] Excluded from spec
[Produces("application/json")] Response content type
[Obsolete] deprecated: true
[JsonPolymorphic] / [JsonDerivedType] discriminator / oneOf with sub-endpoints
[Required], [StringLength], [Range] Schema constraints
XML <summary>, <param>, <returns> Descriptions
XML <example> Example values
[SignalROpenApiRequestExamples] Named request examples
[SignalROpenApiResponseExamples] Named response examples

Request Body Schema

Hub method parameters are mapped to the OpenAPI request body schema:

  • Single complex object parameter (e.g., SendMessage(SendMessageRequest request)): The object's properties are flattened directly into the request body — no wrapper property.
  • Multiple parameters (e.g., SendMessage(string user, string message) or Reply(ChatMessage original, ChatMessage reply)): Each parameter becomes a named property in a wrapper object.
  • Primitive parameters (e.g., string, int): Always wrapped with the parameter name as the property key.

Response Codes

  • 204 No Content: Hub methods returning void or Task (no return value)
  • 200 OK: Hub methods returning Task<T> or streaming results

Examples

Provide multiple named examples for request and response bodies using custom attributes and the ISignalROpenApiExamplesProvider<T> interface.

1. Define a request model and example provider

public class SendMessageRequest
{
    public string User { get; set; } = string.Empty;
    public string Message { get; set; } = string.Empty;
}

public class SendMessageExamplesProvider : ISignalROpenApiExamplesProvider<SendMessageRequest>
{
    public IEnumerable<SignalROpenApiExample<SendMessageRequest>> GetExamples()
    {
        yield return new SignalROpenApiExample<SendMessageRequest>(
            "Greeting",
            new SendMessageRequest { User = "Alice", Message = "Hello, everyone!" })
        {
            Summary = "A friendly greeting",
        };

        yield return new SignalROpenApiExample<SendMessageRequest>(
            "Question",
            new SendMessageRequest { User = "Bob", Message = "What time is the meeting?" })
        {
            Summary = "Asking a question",
        };
    }
}

2. Apply the attribute to a hub method

[SignalROpenApiRequestExamples(typeof(SendMessageExamplesProvider))]
public async Task SendMessage(string user, string message)
{
    await Clients.All.ReceiveMessage(user, message);
}

The examples appear in SwaggerUI's example dropdown for the request body. Response examples work the same way using [SignalROpenApiResponseExamples].

Example providers are resolved from DI first, with Activator.CreateInstance as a fallback.

FluentValidation Integration

The SignalR.OpenApi.FluentValidation package automatically maps FluentValidation rules to OpenAPI schema constraints.

Note: FluentValidation applies to complex object parameters only (classes with properties). Hub methods with primitive parameters (e.g., string user, string message) are not validated — use a request object instead (e.g., SendMessage(SendMessageRequest request)). When a hub method has a single complex object parameter, the schema is flattened — the object's properties appear directly in the request body without a wrapper property.

Setup

builder.Services.AddValidatorsFromAssemblyContaining<MyValidator>();
builder.Services.AddSignalROpenApi();
builder.Services.AddSignalRFluentValidation();

Supported Rules

FluentValidation Rule OpenAPI Schema
NotNull() / NotEmpty() required, nullable: false
NotEmpty() (string) minLength: 1
Length(min, max) / MaximumLength(n) minLength, maxLength
Matches(regex) pattern
GreaterThan(n) minimum + exclusiveMinimum
GreaterThanOrEqualTo(n) minimum
LessThan(n) maximum + exclusiveMaximum
LessThanOrEqualTo(n) maximum
InclusiveBetween(from, to) minimum, maximum
ExclusiveBetween(from, to) minimum, maximum + exclusive flags
EmailAddress() pattern (email regex)

Validators are resolved from DI via IValidator<T>. Nested child validators are supported.

Packages

Package Description
SignalR.OpenApi Core library: hub discovery, OpenAPI generation
SignalR.OpenApi.FluentValidation FluentValidation rules → OpenAPI schema constraints
SignalR.OpenApi.SwaggerUi SwaggerUI with interactive SignalR invocation, streaming, and event monitoring

The following open-source projects also provide OpenAPI, SwaggerUI, or developer tooling for ASP.NET Core SignalR hubs. SignalR.OpenApi was designed with awareness of these projects and aims to combine the best aspects of each.

Feature SignalR.OpenApi SigSpec SignalRSwaggerGen TypedSignalR.Client.DevTools NSwag4SignalR
OpenAPI spec generation ✅ 3.1 ✅ Custom (SigSpec) ✅ Swagger 2.0 / OAS 3.0 ✅ Custom (spec.json) ✅ 3.0
OpenAPI library Microsoft.AspNetCore.OpenApi Custom Swashbuckle IDocumentFilter Custom NSwag IDocumentProcessor
Interactive UI ✅ SwaggerUI (Swashbuckle) ❌ Spec only ✅ Custom (Next.js / Bulma) ✅ SwaggerUI (NSwag)
Real SignalR invocation @microsoft/signalr @microsoft/signalr @microsoft/signalr
Streaming UI ✅ Accumulated history, state tracking, stop button ✅ Server-to-client & client-to-server ✅ PUT operations
Client event monitoring ✅ Real-time event log panel ✅ Event subscription ✅ GET operations
Hub discovery Reflection Reflection Attribute-based ([SignalRHub]) Source generator (MapHub<T>()) Endpoint metadata (HubMetadata)
FluentValidation → schema
Polymorphic types oneOf/discriminator + sub-endpoints
Form-urlencoded input ✅ Flat params & objects
Named examples ✅ Custom attributes + providers
Auth (JWT / Windows) ✅ Built-in SwaggerUI [Authorize] detection accessTokenFactory
Standard attributes [Tags], [EndpointSummary], [Authorize], [Obsolete], etc. Partial [Authorize], custom Partial Partial
Target framework .NET 8+ .NET Core 3.1+ .NET 5+ .NET 6+ .NET 10
NuGet packages 3 packages
Project Description
nswag-fluentvalidation (ZymLabs) FluentValidation → OpenAPI schema mapping for NSwag; rule-based architecture pattern
Swashbuckle.AspNetCore.Filters Request/response examples and security filters for Swashbuckle
Signalr.Hubs.TypeScriptGenerator TypeScript type generation from SignalR hubs (legacy .NET Framework / SignalR 2.x)

License

MIT

Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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 (2)

Showing the top 2 NuGet packages that depend on SignalR.OpenApi:

Package Downloads
SignalR.OpenApi.SwaggerUi

SwaggerUI integration for ASP.NET Core SignalR hubs with interactive invocation, streaming, and client events

SignalR.OpenApi.FluentValidation

FluentValidation integration for SignalR.OpenApi - maps FluentValidation rules to OpenAPI schema constraints

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.429 136 4/29/2026
1.0.429-ci.2026-04-29T08-42... 49 4/29/2026
1.0.403-ci.2026-04-03T06-56... 49 4/3/2026
1.0.320 140 3/20/2026
1.0.320-ci.2026-03-20T08-06... 50 3/20/2026
1.0.320-ci.2026-03-20T07-30... 31 3/20/2026
1.0.320-ci.2026-03-20T06-33... 40 3/20/2026
1.0.320-ci.2026-03-20T05-44... 36 3/20/2026
1.0.319 135 3/19/2026
1.0.319-ci.2026-03-19T17-57... 42 3/19/2026
1.0.319-ci.2026-03-19T07-52... 42 3/19/2026
1.0.319-ci.2026-03-19T05-51... 40 3/19/2026
1.0.318 135 3/18/2026
1.0.318-ci.2026-03-18T08-07... 42 3/18/2026
1.0.226 139 2/26/2026
1.0.226-ci.2026-02-26T08-25... 53 2/26/2026
1.0.226-ci.2026-02-26T04-25... 49 2/26/2026
1.0.223-ci.2026-02-23T05-27... 41 2/23/2026
1.0.223-ci.2026-02-23T04-56... 42 2/23/2026
1.0.223-ci.2026-02-23T04-21... 43 2/23/2026
Loading failed