Skip to content

Conversation

@kimsey0
Copy link
Contributor

@kimsey0 kimsey0 commented Apr 3, 2025

Search for slnx files when setting solution-relative content root

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Fixes #61304

@ghost ghost added the area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions label Apr 3, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Apr 3, 2025
@kimsey0
Copy link
Contributor Author

kimsey0 commented Jul 18, 2025

I think this implementation is both source and binary backwards compatible (except for the semantic change of now looking for slnx files too), but would like someone to verify that.

For already compiled assemblies:

  • Calls to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string solutionName = ".sln") now go to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string solutionName) and keep the old behavior.
  • Calls to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string applicationBasePath, string solutionName = ".sln") now to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string applicationBasePath, string solutionName) and keep the old behavior.

For recompiled assemblies:

  • Calls to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string solutionName = ".sln") that omit the optional parameter now go to builder.UseSolutionRelativeContentRoot(string solutionRelativePath) and get the new support for .slnx files.
  • Calls to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string applicationBasePath, string solutionName = ".sln") that omit the optional parameter (by passing applicationBasePath as a named parameter) now go to builder.UseSolutionRelativeContentRoot(string solutionRelativePath, string applicationBasePath, ReadOnlySpan<string> solutionNames = default) and get the new support for .slnx files.

@kimsey0
Copy link
Contributor Author

kimsey0 commented Jul 18, 2025

Tests are failing for two reasons:

  1. I put the new changes in PublicAPI.Shipped.txt. I'm not sure if this should be in ASP.NET Core 9 or 10, thus Shipped or Unshipped? (Or am I misunderstanding something?)
  2. UseSolutionRelativeContentRoot doesn't currently handle permission errors while climbing the folder hierarchy. I think it would make sense to just have it stop if it encounters an UnauthorizedAccessException, but that is technically an unrelated change. Is it fine to add here?

@kimsey0 kimsey0 marked this pull request as ready for review July 18, 2025 22:22
Copilot AI review requested due to automatic review settings July 18, 2025 22:22
@kimsey0 kimsey0 requested review from a team, halter73 and tdykstra as code owners July 18, 2025 22:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for searching .slnx files (XML-based solution files) when setting solution-relative content roots in the TestHost library. The functionality extends the existing UseSolutionRelativeContentRoot methods to support both traditional .sln and newer .slnx solution files by default.

Key changes:

  • Updated the UseSolutionRelativeContentRoot method to search for both .sln and .slnx files by default
  • Refactored the API to accept multiple solution file patterns via ReadOnlySpan
  • Added comprehensive test coverage for .slnx file support

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
WebHostBuilderExtensions.cs Modified UseSolutionRelativeContentRoot methods to support multiple solution file patterns and added .slnx support
PublicAPI.Shipped.txt Updated public API surface to reflect the new method signatures
UseSolutionRelativeContentRootTests.cs Added comprehensive test coverage for .slnx file detection and multiple solution file scenarios
WebApplicationFactorySlnxTests.cs Added integration tests verifying .slnx support works with WebApplicationFactory

@slang25
Copy link
Contributor

slang25 commented Jul 21, 2025

@danroth27 not sure if this is on the roadmap for aspnetcore 10, but it would be great to get in and allow easy migration of sln → slnx.

Even though this is a feature independent from dotnet and aspnetcore, I predict a lot of folks will adopt this around the .NET 10 time frame, so having the migration work seamlessly will be valuable to many customers.

@danmoseley
Copy link
Member

@halter73 do you have cycles to review this? slnx support does seem valuable for .NET 10

@dotnet-policy-service dotnet-policy-service bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Jul 29, 2025
@kimsey0 kimsey0 closed this Jul 29, 2025
@kimsey0 kimsey0 reopened this Jul 29, 2025
@dotnet-policy-service dotnet-policy-service bot added this to the 10.0-rc1 milestone Jul 29, 2025
Copy link
Member

@halter73 halter73 left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! Can you please open an API Proposal issue for this change? Thanks again.

@halter73 halter73 enabled auto-merge (squash) August 15, 2025 20:15
@halter73 halter73 removed the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Aug 15, 2025
@halter73 halter73 merged commit dcec533 into dotnet:main Aug 16, 2025
29 checks passed
wtgodbe added a commit that referenced this pull request Aug 18, 2025
* Avoid race that can cause Kestrel's RequestAborted to not fire (#62385)

* Send Keep-Alive Ping Immediately When Previous Ping Is Overdue (#63195)

* Make new validations consistent with System.ComponentModel.DataAnnotations behavior (#63231)

* Add support for type-level validation attributes, update validation ordering

* Code review fix, test fix

* Fix trimming annotation

* Fix trimming annotation

* Separate caches for property and type attributes

* Fix typo

Co-authored-by: Brennan <[email protected]>

* Fix typo

Co-authored-by: Brennan <[email protected]>

* Fix and simplify the emitted code

* Update src/Validation/test/Microsoft.Extensions.Validation.GeneratorTests/ValidationsGeneratorTestBase.cs

---------

Co-authored-by: Brennan <[email protected]>
Co-authored-by: Safia Abdalla <[email protected]>

* Search for slnx files when setting solution-relative content root (#61305)

* Address API review feedback for what was IApiEndpointMetadata (#63283)

---------

Co-authored-by: Stephen Halter <[email protected]>
Co-authored-by: Reagan Yuan <[email protected]>
Co-authored-by: Ondřej Roztočil <[email protected]>
Co-authored-by: Brennan <[email protected]>
Co-authored-by: Safia Abdalla <[email protected]>
Co-authored-by: Jacob Bundgaard <[email protected]>
@kimsey0 kimsey0 deleted the patch-1 branch August 19, 2025 11:20
@kimsey0
Copy link
Contributor Author

kimsey0 commented Aug 19, 2025

I just came back from a long vacation. Thanks for carrying this to completion, @slang25 and @halter73. Cheers!

@bkoelman
Copy link
Contributor

Could this change be backported to .NET 8 and 9? Our project (and tests) multi-target 8/9/10, and we're running into the same limitation as described at #61304 (comment) (we have Startup classes in different assemblies).

Without backports, we can't update to slnx until those frameworks are EOL. Unless we try the hack described at #61304 (comment).

@wtgodbe
Copy link
Member

wtgodbe commented Jan 6, 2026

Could this change be backported to .NET 8 and 9?

Unfortunately we can't make API breaking changes in servicing releases. Is the workaround you linked not sufficient?

@halter73
Copy link
Member

halter73 commented Jan 6, 2026

We could consider taking just the behavioral change without the API change. @kimsey0 notes in #61304 (comment) that the .NET 10 change is technically also behaviorally breaking if you have a .slnx file that then shadows a .sln file in a parent folder. But even that can be avoided if we added a test-only, last-ditch fallback to "*.slnx" only if we would otherwise throw an InvalidOperationException for not having found a ".sln" file.

Given the high demand for this, and that we can limit the behavioral change to test projects when an InvalidOperationException would have otherwise been thrown, I think we probably should backport a fix to .NET and .NET 8. I had a Copilot create a PR for release/9.0 at https://github.com/dotnet/aspnetcore/pull/64953/changes that has the limited fix. What do you think @wtgodbe?

@bkoelman
Copy link
Contributor

bkoelman commented Jan 7, 2026

@wtgodbe What I meant to suggest is to backport the behavior change without the API change, as clarified by @halter73. Our only options today are to wait until .NET 9 EOL, or move away from WebApplicationFactory entirety, which affects the majority of 19,000 tests.

@halter73
Copy link
Member

halter73 commented Jan 8, 2026

Our only options today are to wait until .NET 9 EOL, or move away from WebApplicationFactory entirety, which affects the majority of 19,000 tests.

@bkoelman I personally in favor of the backport just to avoid people running into unnexpecged issues when updating .NET 8 and 9 project to use slnx, but couldn't you update your tests to call something like the following?

builder.UseSolutionRelativeContentRoot(typeof(TEntryPoint).Assembly.GetName().Name!, AppContext.BaseDirectory, "*.slnx");

@bkoelman
Copy link
Contributor

bkoelman commented Jan 9, 2026

Our only options today are to wait until .NET 9 EOL, or move away from WebApplicationFactory entirety, which affects the majority of 19,000 tests.

@bkoelman I personally in favor of the backport just to avoid people running into unnexpecged issues when updating .NET 8 and 9 project to use slnx, but couldn't you update your tests to call something like the following?

builder.UseSolutionRelativeContentRoot(typeof(TEntryPoint).Assembly.GetName().Name!, AppContext.BaseDirectory, "*.slnx");

No, that doesn't work because UseSolutionRelativeContentRoot is called internally (resulting in a crash) before we get a chance to call it ourselves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WebApplicationFactory doesn't set solution relative content root if you switch to slnx solution

8 participants