diff --git a/src/OpenApi/src/Services/OpenApiDocumentService.cs b/src/OpenApi/src/Services/OpenApiDocumentService.cs index c594ebb7ac08..bc0094faa108 100644 --- a/src/OpenApi/src/Services/OpenApiDocumentService.cs +++ b/src/OpenApi/src/Services/OpenApiDocumentService.cs @@ -409,6 +409,10 @@ private async Task GetResponseAsync( var targetType = parameter.Type == typeof(string) && parameter.ModelMetadata.ModelType != parameter.Type ? parameter.ModelMetadata.ModelType : parameter.Type; + // If the type is null, then we're dealing with an inert + // route parameter that does not define a specific parameter type in the + // route handler or in the response. In this case, we default to a string schema. + targetType ??= typeof(string); var openApiParameter = new OpenApiParameter { Name = parameter.Name, diff --git a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ParameterSchemas.cs b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ParameterSchemas.cs index 4842e189ade4..671fc166e87a 100644 --- a/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ParameterSchemas.cs +++ b/src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Services/OpenApiSchemaService/OpenApiSchemaService.ParameterSchemas.cs @@ -592,4 +592,22 @@ internal enum ItemStatus Approved = 1, Rejected = 2, } + + [Fact] + public async Task SupportsMvcActionWithAmbientRouteParameter() + { + // Arrange + var action = CreateActionDescriptor(nameof(AmbientRouteParameter)); + + // Assert + await VerifyOpenApiDocument(action, document => + { + var operation = document.Paths["/api/with-ambient-route-param/{versionId}"].Operations[OperationType.Get]; + var parameter = Assert.Single(operation.Parameters); + Assert.Equal("string", parameter.Schema.Type); + }); + } + + [Route("/api/with-ambient-route-param/{versionId}")] + private void AmbientRouteParameter() { } }