aspnetcore: Blazor WASM not loading appsettings.{environment}.json in Azure App Services

Describe the bug

When developing locally (Blazor WASM), I have the following files in /wwwroot:

appsettings.json
appsettings.Development.json
appsettings.LocalDevelopment.json

My launchSettings.json specifies an ASPNETCORE_ENVIRONMENT of “LocalDevelopment”.

When running locally, everything works as expected. appsettings.json and appsettings.LocalDevelopment.json are merged as expected.

I have just published the Blazor WASM app to Azure App Services, and appsettings.json merging fails. I have the ASPNETCORE_ENVIRONMENT set to “Development” in the App Service:

image

I have been able to confirm the failure by putting all of my settings in appsettings.json so that I don’t need to rely on merging. The app runs as expected in the App Service.

To Reproduce

1: Create a new Blazor WASM ASP.NET Core Hosted application 2: Add appsettings.json, and appsettings.Development.json to /wwwroot 3: Add a configuration value to both files that requires merging. 4: Locally, set ASPNETCORE_ENVIRONMENT to “Development” 5: Confirm that the correct config value gets read 6: Deploy to Azure App Service 7: Set ASPNETCORE_ENVIRONMENT to “Development” for the App Service 8: BUG: Note that value is not read from appsettings.Development.json. It is read from appsettings.json.

Further technical details

  • ASP.NET Core version 3.1
  • Include the output of dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19041
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  2.1.700 [C:\Program Files\dotnet\sdk]
  2.1.701 [C:\Program Files\dotnet\sdk]
  2.1.801 [C:\Program Files\dotnet\sdk]
  2.2.300 [C:\Program Files\dotnet\sdk]
  2.2.301 [C:\Program Files\dotnet\sdk]
  2.2.401 [C:\Program Files\dotnet\sdk]
  3.0.100 [C:\Program Files\dotnet\sdk]
  3.1.101 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  • The IDE (VS / VS Code/ VS4Mac) you’re running on, and it’s version - Visual Studio 2019 v16.7.2

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 14
  • Comments: 51 (7 by maintainers)

Most upvoted comments

@mkArtakMSFT

I’m curious why this is considered minor severity and has been pushed from Next sprint planning? This is a pretty major issue and a deviation from how everything else in the .NET Core ecosystem works. It also makes managing configuration across environments very difficult. We have to manually edit appSettings.json to match the environment we’re about to deploy to every single time we need to do a deployment.

I’m surprised that this issue hasn’t been reported frequently. Am I missing something?

Thanks for contacting us. We’re moving this issue to the .NET 8 Planning milestone for future evaluation / consideration. Because it’s not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

Thanks for contacting us. We’re moving this issue to the .NET 7 Planning milestone for future evaluation / consideration. Because it’s not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

Why is this not fixed? The issue was reported 2 years ago.

ball dropped

I reported this back in reported this in May of 2020 #21992 and it is still a lingering issues in .net Core 3.1, .net 5 and potentially .net 6? We are now a year and a half removed and this is still not fixed. Unless you have 2 environment, it is unthinkable that this could be an acceptable state.

Incase anyone would like to know, I was able to work around it by adding a second environment variable enviro and set that to my sites environment (dev, qa, uat, prod, etc.). I read that variable out like I would ASPNETCORE_ENVIRONMENT and created a middleware that sets the blazor-environment header with this value. This allows hosted WASM sites to properly pull in the environment from inside Blazor and things work as they should. It also allows me to pull in the proper appsettings.*.json files on the server.

I hope that one day this gets solved by the framework.

Thanks for contacting us. We’re moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

“affected-very-few”, “severity-minor”, “.NET 7 planning” - utterly ridiculous. This is such a fundamental aspect of app configuration and there is no stable workaround. Thanks a bunch Microsoft.

Agreed, I don’t understand how this is minor and very few affected. This makes Blazor WASM unusable in a production environment. Can someone from the team explain how this is a minor issue? What is the recommended method for deploying into multiple environments with the same code?

Here is the very hacky workaround that we ended up with in the index.html file we replaced:

<script src="_framework/blazor.webassembly.js"></script>

with:

    <script src="_framework/blazor.webassembly.js" autostart="false"></script>
    <script>
        if (window.location.hostname.includes("localhost") || window.location.hostname.includes("dev")) {
            Blazor.start({
                environment: "Development"
            });
        }
        else if (window.location.hostname.includes("demo")) {
            Blazor.start({
                environment: "Demo"
            });
        }
        else if (window.location.hostname.includes("stage")) {
            Blazor.start({
                environment: "Staging"
            });
        }
        else {
            Blazor.start({
                environment: "Production"
            });
        }
    </script>

I’d love to see updates on this, as well. I see the “affected-very-few” label, but I feel like there is a fundamental and subtle issue with appsettings and non-dotnet blazorwasm hosts.

We solved it like this:

  1. In Visual Studio project properties -> “Build Event” -> “Pre-build event command line”, add the following line: echo window.BlazorEnvironment = '$(ConfigurationName)'; > $(ProjectDir)wwwroot\js\BlazorEnvironment.js

  2. In index.html, BEFORE bootstrapping Blazor with this tag: <script src="_framework/blazor.webassembly.js"></script>, add the following to make sure the “blazor-environment” header is set to the correct value:

<script src="js/BlazorEnvironment.js"></script>
<script>
    const originalFetch = fetch;
    fetch = async (url, options) => {
        const response = await originalFetch(url, options);
        return url.endsWith('/blazor.boot.json')
            ? new Response(await response.blob(), { headers: { 'blazor-environment': window.BlazorEnvironment } })
            : response;
    };
</script>

@CameronVetter I’m just a user of Blazor like you. It seems like a lot of things, not just Blazor, are pushed to the .NET7 milestone. I have several shims in Blazor for the time being until .NET 7 is GA. I’ve just been working around it in the meantime.

My post above seems to be working great without needing to set the environment via javascript. Blazor reads the “blazor-environment” http header when loading blazor.boot.json. I’d recommend going that route for the time being as the static files response shim takes care of the 1 piece in the recommended pathway that is not currently working which is the blazor hosted environment should be setting the header value without manual intervention.

There are numerous hacky workarounds in this thread that work. My question was for someone from Microsoft on this team that is deciding not to fix this to give us an answer on what the approach should be since what is documented doesn’t work.

Any updates on this? Not sure how this could be treated as a minor issue!!! The entire development and debugging (via visual studio) works just fine and it blasts out on the very first deployment (I’m using docker with Nginx as the server).

While it is logical to think that “Environment Variable” does not make sense for a static website application, it is very sad that no proper warning is provided in the MSDN - https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/configuration?view=aspnetcore-5.0

From the source code, it is evident that app settings transformation will work ONLY for ASPNET hosted WASM apps, and for the rest of others, it will default to “Production”:

image https://github.com/dotnet/aspnetcore/blob/6a929c3796f048d619bdd05969972d3a84669aac/src/Components/Web.JS/src/Platform/BootConfig.ts#L5


UPDATE - My Workaround


As I’m deploying the Blazor wasm in a Linux container (as Nginx as the server), I did the config “transform” during the build process. Updated docker file (pasting only relevant parts):

FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
..... deleting copy and restore lines for brevity...........
RUN dotnet publish "myblazorproj.csproj" -c Release -o /app/publish

# Use official nginx image as the base image
FROM nginx:latest as final
ARG BUILD_ENVIRONMENT
RUN echo $BUILD_ENVIRONMENT

COPY ./nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/publish/wwwroot /usr/share/nginx/html
# This is to fix the bug mentioned here - https://github.com/dotnet/aspnetcore/issues/25152
# Everything works (appsettings transformation) during local debugging, but the environment is not getting picked properly on publish
# Fixing it by replacing the appsettings.json file with the env specific file
# NOTE - This is a blind file replace and hence appsettings transformation will not work; make sure all settings are present in the enc specifci files as well 
COPY --from=build /app/publish/wwwroot/appsettings.${BUILD_ENVIRONMENT}.json /usr/share/nginx/html/appsettings.json

EXPOSE 80

And during Docker build, pass the argument BUILD_ENVIRONMENT=<your_enviornment_name_matching_the_env_json>

Blazor WASM can’t read the Environment variables. MS has two documented options here, https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/environments?view=aspnetcore-5.0 Either, set the env in JS on in the web.config by setting a http header that Blazor can read.

I’m using the web.config approach and have my ci/cd pipeline replace the environment on build.

It seems it is not only an Azure problem, the same problem occurs on local machines as well. I followed the instructions told in https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-5.0 and then I do receive a HTTP 404 Not Found error message, Blazor WASM does not start at all. It seems it only works with one single or only in specific environments. The problem was also discussed here: https://github.com/dotnet/aspnetcore/issues/21992 - The answer was there that the problem will not be fixed in the near future by Microsoft. But in companies, multiple environments are often needed, e.g. if the same Blazor WASM shall e.g. run in two different production environments with different app settings. I would also love to have multiple environment support in Blazor WASM as soon as possible.

To learn more about what this message means, what to expect next, and how this issue will be handled you can read our Triage Process document. We’re moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. Because it’s not immediately obvious what is causing this behavior, we would like to keep this around to collect more feedback, which can later help us determine how to handle this. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact work.

The issue has been figured out and is an issue with case sensitivity. Saying its “not immediately obvious” is not a correct assessment. Please see @jasonshave comment above… This should be fixed ASAP, this has a huge impact and is a minor fix @mkArtakMSFT

To learn more about what this message means, what to expect next, and how this issue will be handled you can read our Triage Process document. We’re moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. Because it’s not immediately obvious what is causing this behavior, we would like to keep this around to collect more feedback, which can later help us determine how to handle this. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it’s very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact work.

You can still use this:

var env = "dev";
var builder = new ConfigurationBuilder();
builder.AddJsonFile("appsettings.json");
builder.AddJsonFile($"appsettings.{env}.json");

You just need to set env from somewhere. I guess it depends on how you are hosting your app.

I like @gilm0079 use of the UseStaticFiles middleware. I might even modify my code to do that to help not expose that in every API call i make to my backend. I’m not fond of using a URL or hostname to try and figure out what environment is being used (qa/staging/test are all urls used in my environments for the same stage of deployment).

I did see this was added to the .NET 7 preview milestone last month, is there active work being done on this issue? It’s been a outstanding issue since Blazor’s launch (not sure why my issue was closed #21992 about this.) I would love to tell my Architecture team we don’t need an extra environment variable and we can go back to using ASPNETCORE_ENVIRONMENT.

It still is a bit hard to understand how this isn’t an issue for more people and how the Blazor team doesn’t see this as a critical issue.

Same issue here. @CameronVetter 's work-around is working for us, Thank you for sharing it.

I did have to make sure it was authentication line below: <script src="_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js"></script>

We switched the standalone WASM application to hosted WASM application and followed the environment approach described in https://docs.microsoft.com/en-us/aspnet/core/blazor/fundamentals/environments?view=aspnetcore-6.0#set-the-environment-for-azure-app-service.

Same problem here, Microsoft wtf do you wanna fix that ?!

Any update on progress on this feature?