Skip to content

Handle leading slash on route prefix during index.html GET - #4084

Merged
martincostello merged 2 commits into
domaindrivendev:masterfrom
superstator:index_html_route
Jul 24, 2026
Merged

martincostello merged 2 commits into
domaindrivendev:masterfrom
superstator:index_html_route

Conversation

@superstator

Copy link
Copy Markdown
Contributor

Pull Request

The issue or feature being addressed

Minor bug encountered in #4083

Details on the issue fix or feature implementation

This change modifies the regular expression used in SwaggerUIMiddleware.cs (line 58) to allow matching when _options.RoutePrefix contains a leading /. A similar regular expression is used on line 46 to match the route and return a redirect to index.html, but it already handles the presence or absence of a leading /, so this change simply brings them more in sync.

@codecov

codecov Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

❌ 6 Tests Failed:

Tests completed Failed Passed Skipped
1152 6 1146 0
View the top 3 failed test(s) by shortest run time
TestFirst.IntegrationTests.CreateProductTests::CreateProduct_Returns201_IfContentIsValid
Stack Traces | 0.001s run time
at Microsoft.OpenApi.Reader.OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.Reader.OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerOptionsExtensions.AddOpenApiFile(ApiTestRunnerOptions options, String documentName, String filePath) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerOptionsExtensions.cs:line 15
   at TestFirst.IntegrationTests.ApiTestRunner.<>c.<.ctor>b__0_0(ApiTestRunnerOptions c) in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 18
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerBase.Configure(Action`1 setupAction) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs:line 20
   at TestFirst.IntegrationTests.ApiTestRunner..ctor() in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 11
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
TestFirst.IntegrationTests.CreateProductTests::CreateProduct_Returns400_IfContentIsInValid
Stack Traces | 0.001s run time
at Microsoft.OpenApi.Reader.OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.Reader.OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerOptionsExtensions.AddOpenApiFile(ApiTestRunnerOptions options, String documentName, String filePath) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerOptionsExtensions.cs:line 15
   at TestFirst.IntegrationTests.ApiTestRunner.<>c.<.ctor>b__0_0(ApiTestRunnerOptions c) in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 18
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerBase.Configure(Action`1 setupAction) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs:line 20
   at TestFirst.IntegrationTests.ApiTestRunner..ctor() in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 11
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
TestFirst.IntegrationTests.CreateUserTests::CreateUser_Returns201_IfContentIsValid
Stack Traces | 0.001s run time
at Microsoft.OpenApi.Reader.OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.Reader.OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerOptionsExtensions.AddOpenApiFile(ApiTestRunnerOptions options, String documentName, String filePath) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerOptionsExtensions.cs:line 15
   at TestFirst.IntegrationTests.ApiTestRunner.<>c.<.ctor>b__0_0(ApiTestRunnerOptions c) in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 18
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerBase.Configure(Action`1 setupAction) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs:line 20
   at TestFirst.IntegrationTests.ApiTestRunner..ctor() in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 11
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
TestFirst.IntegrationTests.CreateUserTests::CreateUser_Returns400_IfContentIsInValid
Stack Traces | 0.001s run time
at Microsoft.OpenApi.Reader.OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.Reader.OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerOptionsExtensions.AddOpenApiFile(ApiTestRunnerOptions options, String documentName, String filePath) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerOptionsExtensions.cs:line 15
   at TestFirst.IntegrationTests.ApiTestRunner.<>c.<.ctor>b__0_0(ApiTestRunnerOptions c) in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 18
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerBase.Configure(Action`1 setupAction) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs:line 20
   at TestFirst.IntegrationTests.ApiTestRunner..ctor() in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 11
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
TestFirst.IntegrationTests.GetProductsTests::GetProducts_Returns200_IfRequiredParametersProvided
Stack Traces | 0.001s run time
at Microsoft.OpenApi.Reader.OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.Reader.OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerOptionsExtensions.AddOpenApiFile(ApiTestRunnerOptions options, String documentName, String filePath) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerOptionsExtensions.cs:line 15
   at TestFirst.IntegrationTests.ApiTestRunner.<>c.<.ctor>b__0_0(ApiTestRunnerOptions c) in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 18
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerBase.Configure(Action`1 setupAction) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs:line 20
   at TestFirst.IntegrationTests.ApiTestRunner..ctor() in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 11
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
TestFirst.IntegrationTests.GetProductsTests::GetProducts_Returns400_IfRequiredParametersMissing
Stack Traces | 0.001s run time
at Microsoft.OpenApi.Reader.OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.Reader.OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Microsoft.OpenApi.OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerOptionsExtensions.AddOpenApiFile(ApiTestRunnerOptions options, String documentName, String filePath) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerOptionsExtensions.cs:line 15
   at TestFirst.IntegrationTests.ApiTestRunner.<>c.<.ctor>b__0_0(ApiTestRunnerOptions c) in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 18
   at Swashbuckle.AspNetCore.ApiTesting.ApiTestRunnerBase.Configure(Action`1 setupAction) in ....../_/src/Swashbuckle.AspNetCore.ApiTesting/ApiTestRunnerBase.cs:line 20
   at TestFirst.IntegrationTests.ApiTestRunner..ctor() in .../test/WebSites/TestFirst.IntegrationTests/ApiTestsSetup.cs:line 11
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@martincostello martincostello left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - would you mind adding a test somewhere that would have caught this?

@superstator

superstator commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Sure, I didn't see a unit test project for SwaggerUI specifically, should this test go somewhere else or would you like me to add a new test project for SwaggerUI?

Nevermind, I see it's covered by integration tests. I'll try to fit something in there to include a route prefix with leading /.

@superstator

Copy link
Copy Markdown
Contributor Author

I didn't love the idea of creating new test sites just for the route prefix, so instead I added some extra Startup classes to the Basic site. Let me know if you'd prefer a different approach.

@martincostello martincostello added this to the v10.2.4 milestone Jul 24, 2026
@martincostello
martincostello merged commit 7018e3f into domaindrivendev:master Jul 24, 2026
18 of 19 checks passed
@martincostello

Copy link
Copy Markdown
Collaborator

Thanks!

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Thanks for your contribution @superstator - the changes from this pull request have been published as part of version 10.3.0 📦, which is now available from NuGet.org 🚀

This was referenced Oct 7, 2026
This was referenced Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants