Skip to content

Commit ac47b75

Browse files
committed
Change OpenAPI document name resolution to be case-insensitive
1 parent 78ef1b0 commit ac47b75

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

src/OpenApi/src/Extensions/OpenApiServiceCollectionExtensions.cs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,35 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services, st
5757
ArgumentNullException.ThrowIfNull(services);
5858
ArgumentNullException.ThrowIfNull(configureOptions);
5959

60-
services.AddOpenApiCore(documentName);
61-
services.Configure<OpenApiOptions>(documentName, options =>
60+
// We need to store the document name in a case-insensitive manner
61+
// to support case-insensitive document name resolution.
62+
// Keyed Services are case-sensitive by default, which doesn't work well for document names in ASP.NET Core
63+
// as routing in ASP.NET Core is case-insensitive by default.
64+
var lowercasedDocumentName = documentName.ToLowerInvariant();
65+
66+
AddOpenApiCore(services, lowercasedDocumentName);
67+
services.Configure<OpenApiOptions>(lowercasedDocumentName, options =>
6268
{
63-
options.DocumentName = documentName;
69+
options.DocumentName = lowercasedDocumentName;
6470
configureOptions(options);
6571
});
6672
return services;
73+
74+
// The reason this method is a local function is to prevent case-sensitive document names being passed into this method (from other methods) in the future.
75+
static IServiceCollection AddOpenApiCore(IServiceCollection services, string documentName)
76+
{
77+
services.AddEndpointsApiExplorer();
78+
services.AddKeyedSingleton<OpenApiSchemaService>(documentName);
79+
services.AddKeyedSingleton<OpenApiSchemaStore>(documentName);
80+
services.AddKeyedSingleton<OpenApiDocumentService>(documentName);
81+
// Required for build-time generation
82+
services.AddSingleton<IDocumentProvider, OpenApiDocumentProvider>();
83+
// Required to resolve document names for build-time generation
84+
services.AddSingleton(new NamedService<OpenApiDocumentService>(documentName));
85+
// Required to support JSON serializations
86+
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<JsonOptions>, OpenApiSchemaJsonOptions>());
87+
return services;
88+
}
6789
}
6890

6991
/// <summary>
@@ -99,19 +121,4 @@ public static IServiceCollection AddOpenApi(this IServiceCollection services, Ac
99121
/// </example>
100122
public static IServiceCollection AddOpenApi(this IServiceCollection services)
101123
=> services.AddOpenApi(OpenApiConstants.DefaultDocumentName);
102-
103-
private static IServiceCollection AddOpenApiCore(this IServiceCollection services, string documentName)
104-
{
105-
services.AddEndpointsApiExplorer();
106-
services.AddKeyedSingleton<OpenApiSchemaService>(documentName);
107-
services.AddKeyedSingleton<OpenApiSchemaStore>(documentName);
108-
services.AddKeyedSingleton<OpenApiDocumentService>(documentName);
109-
// Required for build-time generation
110-
services.AddSingleton<IDocumentProvider, OpenApiDocumentProvider>();
111-
// Required to resolve document names for build-time generation
112-
services.AddSingleton(new NamedService<OpenApiDocumentService>(documentName));
113-
// Required to support JSON serializations
114-
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<JsonOptions>, OpenApiSchemaJsonOptions>());
115-
return services;
116-
}
117124
}

0 commit comments

Comments
 (0)