Search code examples
asp.net-coreazure-devopsazure-web-app-serviceblazor-server-sideasp.net-core-css-isolation

Scoped CSS issue in Blazor Server


I am working on a Blazor Server app (.NET 7) deployed to an Azure App Service and looking to make some changes to the theme, starting with the Navbar.

In a standard Blazor app scaffold the MainLayout.razor and NavBar.razor components both have a scoped css file, MainLayout.razor.css and NavBar.razor.css respectively.

I can make changes (just colors) to these files and run the app locally and it works perfectly.

However, once the app is deployed, it's like the changes are not there. It uses the old css from the original template. This is NOT a browser cache issue, as I have cleared this repeatedly, used private windows, different browsers, different machines etc.

The only difference I can see is that the build configuration for the deploy is "Release" as opposed to "Development" when run locally. So I tried changing this option in my pipeline to see if that fixes it (even though this would not be a good solution) and the result was the same - the "old" css is used.

The weird thing is that if I run locally with the "Release" build option, I get no scoped CSS at all. The components get nothing, and render as plain text...

I saw some other posts which recommended setting the host to use static web assets, so adding to program.cs:

builder.WebHost.UseStaticWebAssets();

This works locally (even with "Release" build configuration), however when deployed this causes the app service container to crash on startup. I also am specifically told NOT to use this option in deployed apps in Microsoft's documentation here:

https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/static-files?view=aspnetcore-7.0#static-files-in-non-development-environments-for-blazor-server-apps

I also suspected that this is actually something strange with the Azure App Service, however this is a development slot which has no other services in front of it which could be caching the css.

I thought perhaps the app service itself was doing this, but it has now been several days since code with the old css has been deployed to this slot, so I do not think this is the case.

I also referred to the documentation here:

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/css-isolation?view=aspnetcore-7.0

And according to those docs these scoped css files should "just work", however I went ahead and explicitly set the below options just to be sure:

<PropertyGroup>
  <DisableScopedCssBundling>false</DisableScopedCssBundling>
  <ScopedCssEnabled>true</ScopedCssEnabled>
</PropertyGroup>

And still no result.

I have now tried deploying the app to a brand new app service slot, and I found that it is not getting ANY of the scoped CSS (just like when I test the Release build locally) -- the page loads in plain text on this fresh slot.

So probably I have broken something with css isolation in the app - but it is not apparent where or how this could have occurred. Any tips on where to look on this would be appreciated.

I have found now that the build/deploy pipeline was not including ANY css in the published zip package. This turned out to be due to the way the pipeline was set up. What is still mysterious to me is how it ever worked before, but I have the fix now so that's not so important anymore.

The relevant section of the pipeline code was:

    steps:
    - task: UseDotNet@2
      inputs:
       installationPath: $(Agent.ToolsDirectory)/dotnet
       packageType: sdk
       version: 7.x
      
    - task: DotNetCoreCLI@2
      inputs:
        command: 'build'
        configuration: $(buildConfiguration)
        projects: |
          $(workingDirectory)/*.csproj
        arguments: --output $(System.DefaultWorkingDirectory)/publish_output --configuration $(buildConfiguration)

    - task: ArchiveFiles@2
      displayName: 'Archive files'
      inputs:
        rootFolderOrFile: '$(System.DefaultWorkingDirectory)/publish_output'
        includeRootFolder: false
        archiveType: zip
        archiveFile: $(Build.ArtifactStagingDirectory)/web-$(Build.BuildId).zip
        replaceExistingArchive: true

    - publish: $(Build.ArtifactStagingDirectory)/web-$(Build.BuildId).zip
      artifact: drop

What this does is running the build in 'Release' mode, zips up the build output, and dropping it in the Pipeline workspace for the deploy step to pick up after. The problem is it does not include any of the needed css assets.


Solution

  • It does look like an issue I had in the past. Here is the S.O. that I opened to find the solution Azure include {Assembly}.styles.css in generated packages

    I was missing the publish part of the pipeline.

    • task: DotNetCoreCLI@2

    displayName: 'dotnet publish'

    inputs:

    command: publish

    projects: |

    '**\xxx.csproj'

    configuration: 'Release'

    arguments: '--output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)'