Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebApplicationOptions.WebRootPath is ignored if a wwwroot folder exists #40613

Closed
1 task done
space-alien opened this issue Mar 9, 2022 · 12 comments
Closed
1 task done
Assignees
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-static-web-assets

Comments

@space-alien
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

If a wwwroot folder exists, content is served from that location even though WebApplicationOptions.WebRootPath has been specified.

In my development environment, I want to serve my web app from uncompiled sources. In production, my web app is compiled into the wwwroot folder. I switch the web root path on the development environment variable as shown below. (This is the only way I could find in .NET 6, whereas before it was trivial to set the IWebHostEnvironment.WebRootPath property).

I am now forced to rename the production wwwroot folder to something else, in order to circumvent this default behaviour.

WebApplicationBuilder builder;
{
    WebApplicationOptions opts;

    if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == Environments.Development)
    {
        var path = Path.Combine(
            Directory.GetParent(Environment.CurrentDirectory.TrimEnd('\\'))!.ToString(),
            "MyWebAppDevSources");

        opts = new()
        {
            Args = args,
            WebRootPath = path,
        };
    }
    else
    {
        opts = new()
        {
            Args = args,
            WebRootPath = "webroot", // Forced to use a different location in Production,
                                     // just to avoid having requests being served from the
                                     // `wwwroot` folder in Development mode.
        };
    }

    builder = WebApplication.CreateBuilder(opts);
}

Expected Behavior

I expect the WebApplicationOptions.WebRootPath property to always take precedence even when there is a default wwwroot folder on disk.

I also wish there were a way to set this property after instantiating the WebApplicationBuilder.

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

6.0.200

Anything else?

No response

@adityamandaleeka
Copy link
Member

adityamandaleeka commented Mar 11, 2022

I expect the WebApplicationOptions.WebRootPath property to always take precedence even when there is a default wwwroot folder on disk.

That's what should be happening now.

Here's the code that defaults to 'wwwroot':

As you can see it should only be setting it to 'wwwroot' if options.WebRoot is null.

If this doesn't match what you're seeing, please share a minimal repro app on GitHub and we'll take a look.

@space-alien
Copy link
Author

Here is an ultra-minimal repro that demonstrates the problem: https://github.com/space-alien/AspNetWebRootPath

@adityamandaleeka
Copy link
Member

@space-alien Thank you for providing that. I took a look and your description of the behavior is right.

It looks like something in the static asset manifest generation logic is eagerly matching wwwroot if it exists. I can see that when the wwwroot directory is present, it gets added to the beginning of ContentRoots in the staticwebassets.runtime.json.

@javiercn Can you please take a look and/or reroute this issue?

@javiercn
Copy link
Member

@adityamandaleeka will take a look.

@adityamandaleeka adityamandaleeka added feature-static-web-assets area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates and removed area-runtime labels Mar 14, 2022
@javiercn
Copy link
Member

javiercn commented Mar 17, 2022

@space-alien The content from the wwwroot is served because those files are considered static web assets. If you want to change where the files are being served from to avoid this you have several options:

  • Disable static web assets completely:
    • This means content from razor class libraries won't work.
  • Prevent the files inside the wwwroot from being considered content using <Content Remove="wwwroot\**" /> inside an item group on your csproj file.
    • You might need to do further adjustments when you prepare for publishing.

Alternatively, if you provide a bit more details on your scenario, I might be able to suggest alternative options that might be simpler to accomplish the same goal.

@javiercn javiercn added the Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. label Mar 17, 2022
@ghost
Copy link

ghost commented Mar 17, 2022

Hi @space-alien. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

@space-alien
Copy link
Author

space-alien commented Mar 18, 2022

@javiercn Thank you for your reply, Javier. I have found a workaround in my project, but I think the question is whether the current behaviour is desirable or intuitive. It certainly cost me a lot of time.

My repro demonstrates how even though WebApplicationOptions.WebRootPath has been specified, if a wwwroot folder exists, the requested content is preferentially served from that location. WebRootPath takes lower priority. This seems counter-intuitive.

I would expect the WebApplicationOptions.WebRootPath property to override wwwroot, so that wwwroot would not be served even if it exists.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Mar 18, 2022
@javiercn
Copy link
Member

@space-alien

My repro demonstrates how even though WebApplicationOptions.WebRootPath has been specified, if a wwwroot folder exists, the requested content is preferentially served from that location. WebRootPath takes lower priority.

What's happening here is that there are two features that are not interacting great together in this scenario. Each feature is doing what it is supposed to do.

None of the features have specific knowledge of where you are serving the files from, they both have a convention that by default looks at the wwwroot folder. One of them does it at compile time (static web assets) and the other one at runtime (WebRootPath).

At the base layer, IWebHostEnvironment offers a convention that defines where files are served from (which defaults to wwwroot) at runtime, which is used during publish. However since a few releases ago, we have another feature that builds on top and takes control over how assets are served during development (which is static web assets), so if you want to change where files are served from during development, you need to either disable the feature (which breaks content from razor class libraries) or update the configuration in static web assets to reflect your convention.

Static web assets when enabled are responsible for defining the content for the app at build and publish time, so they need to be in control, during development, to offer a coherent view between the assets being served during development and the assets being served in production.

I understand in your case it might not match your expectations, but the alternative might result in other unexpected behaviors that are really hard to debug in much more common scenarios (where the two features are using the conventions), so I think the behavior here is expected and by design.

It might be worth for us updating the documentation to cover this case.

That said, I would like to understand more about your scenario, since there are likely other alternative ways to achieve the same result that might require less tunning.

@javiercn javiercn added Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. and removed Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. labels Mar 21, 2022
@ghost
Copy link

ghost commented Mar 21, 2022

Hi @space-alien. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

tjololo added a commit to Altinn/altinn-studio that referenced this issue Mar 24, 2022
* remove .yarn folder from dockerignore
* add InvariantGlobalization false https://docs.microsoft.com/en-us/answers/questions/728280/running-net-6-project-in-docker-throws-globalizati.html
* remove staticwebassets.runtime.json after build dotnet/aspnetcore#40613
tjololo added a commit to Altinn/altinn-studio that referenced this issue Mar 25, 2022
* remove .yarn folder from dockerignore
* add InvariantGlobalization false https://docs.microsoft.com/en-us/answers/questions/728280/running-net-6-project-in-docker-throws-globalizati.html
* remove staticwebassets.runtime.json after build dotnet/aspnetcore#40613
@ghost
Copy link

ghost commented Mar 25, 2022

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

See our Issue Management Policies for more information.

@space-alien
Copy link
Author

@javiercn Thanks Javier. I have avoided the issue in my project by forcing the production assets into a subfolder of wwwroot and switching the PhysicalFileProvider path on the environment variable. This isn't exactly the same as before, but it happens to suit my case.

Yes, I agree that perhaps updating the documentation to cover this behaviour might be helpful for other users.

@ghost ghost added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. Status: No Recent Activity labels Mar 26, 2022
@javiercn
Copy link
Member

Filed dotnet/AspNetCore.Docs#25446 to improve the docs for this scenario.

@javiercn javiercn removed the Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. label Mar 28, 2022
@dotnet dotnet locked as resolved and limited conversation to collaborators Apr 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-static-web-assets
Projects
None yet
Development

No branches or pull requests

3 participants