Skip to content

Omitting GroupNameFormat causes Service Provider Exceptions #1176

@sander1095

Description

@sander1095

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

In our recent email conversations, you said:

- The statement about options.GroupNameFormat = "'v'VVV" isn’t entirely accurate
    - Setting this is a not a hard requirement for OpenAPI

I believe this isn't true. Perhaps it is on a technical level, but exceptions occur when it is missing.

You can find the runnable sample here. Just comment out the GroupNameFormat and navigate to /openapi/v1.json, and you'll see an exception.

using Asp.Versioning;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddApiVersioning(options =>
{
    options.ReportApiVersions = true;

    options.DefaultApiVersion = new ApiVersion(1, 0);

    options.AssumeDefaultVersionWhenUnspecified = false;

    options.ApiVersionReader = new QueryStringApiVersionReader("api-version");

})
.AddApiExplorer(options =>
{
    // We are NOT setting GroupNameFormat. This causes:
    // InvalidOperationException: This service provider doesn't support keyed services.
    // Microsoft.Extensions.DependencyInjection.ServiceProviderKeyedServiceExtensions.GetKeyedService(IServiceProvider provider, Type serviceType, object serviceKey) 
    // options.GroupNameFormat = "'v'VVV";
})
.AddMvc()
.AddOpenApi();

var app = builder.Build();

app.MapOpenApi().WithDocumentPerVersion();

app.MapControllers();

app.Run();

The exception:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: This service provider doesn't support keyed services.
         at Microsoft.Extensions.DependencyInjection.ServiceProviderKeyedServiceExtensions.GetKeyedService(IServiceProvider provider, Type serviceType, Object serviceKey)
         at Microsoft.Extensions.DependencyInjection.KeyedServiceContainer.GetKeyedService(Type serviceType, Object serviceKey) 
         at Microsoft.Extensions.DependencyInjection.ServiceProviderKeyedServiceExtensions.GetKeyedService[T](IServiceProvider provider, Object serviceKey)
         at Microsoft.AspNetCore.Builder.OpenApiEndpointRouteBuilderExtensions.<>c__DisplayClass0_0.<<MapOpenApi>b__0>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F0399B8B15BE443123F4BECEE84B112C1912EE3F44D9DDD7BFA38E371FB917343__GeneratedRouteBuilderExtensionsCore.<>c__DisplayClass2_0.<<MapGet0>g__RequestHandler|5>d.MoveNext()       
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Expected Behavior

Either:

  • A clear exception (and documentation/explanation) that GroupNameFormat has to be set
  • A Roslyn analyzer that warns me that GroupNameFormat isnt set and will cause issues
  • A different library design that doesn't allow me to configure API Versioning + OpenAPI in an incompatible way

Steps To Reproduce

Go to openapi/v1.json

using Asp.Versioning;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddApiVersioning(options =>
{
    options.ReportApiVersions = true;

    options.DefaultApiVersion = new ApiVersion(1, 0);

    options.AssumeDefaultVersionWhenUnspecified = false;

    options.ApiVersionReader = new QueryStringApiVersionReader("api-version");

})
.AddApiExplorer(options =>
{
    // We are NOT setting GroupNameFormat. This causes:
    // InvalidOperationException: This service provider doesn't support keyed services.
    // Microsoft.Extensions.DependencyInjection.ServiceProviderKeyedServiceExtensions.GetKeyedService(IServiceProvider provider, Type serviceType, object serviceKey) 
    // options.GroupNameFormat = "'v'VVV";
})
.AddMvc()
.AddOpenApi();

var app = builder.Build();

app.MapOpenApi().WithDocumentPerVersion();

app.MapControllers();

app.Run();

Exceptions (if any)

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: This service provider doesn't support keyed services.
at Microsoft.Extensions.DependencyInjection.ServiceProviderKeyedServiceExtensions.GetKeyedService(IServiceProvider provider, Type serviceType, Object serviceKey)
at Microsoft.Extensions.DependencyInjection.KeyedServiceContainer.GetKeyedService(Type serviceType, Object serviceKey)
at Microsoft.Extensions.DependencyInjection.ServiceProviderKeyedServiceExtensions.GetKeyedService[T](IServiceProvider provider, Object serviceKey)
at Microsoft.AspNetCore.Builder.OpenApiEndpointRouteBuilderExtensions.<>c__DisplayClass0_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F0399B8B15BE443123F4BECEE84B112C1912EE3F44D9DDD7BFA38E371FB917343__GeneratedRouteBuilderExtensionsCore.<>c__DisplayClass2_0.<g__RequestHandler|5>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

.NET Version

10

Anything else?

No response

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions