2

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.

  • could you pls share more details about how you did? because I can't reproduce the issue. – Tiny Wang Mar 09 '23 at 06:44
  • Just change anything in one of the mentioned files, the changes never make it to the deployed app and do not appear in Release builds. – user18901997 Mar 09 '23 at 06:56
  • could you please try to delete the bin and obj folder in the project and then build and publish again? – Tiny Wang Mar 09 '23 at 07:03
  • 1
    I'm not publishing from my local machine, it's publishing using an Azure DevOps pipeline - so those folders don't exist in that context, it should be fresh every time. – user18901997 Mar 09 '23 at 07:09
  • From dev tools of the browser could you check wich request fails? I expect that at least one .css file gave HTTP not found error. There are other parts of program.cs that are executed only in development envirnoment? – Roberto Ferraris Mar 09 '23 at 07:19
  • Check also the solution for [Blazor cannot find or is ignoring scoped CSS](https://stackoverflow.com/questions/69069507/blazor-cannot-find-or-is-ignoring-scoped-css) – Roberto Ferraris Mar 09 '23 at 07:21
  • It all fails, NONE of the css files can be accessed. I found an issue with my pipeline where it was not including the css at all - I'm updating the question and adding the answer shortly. – user18901997 Mar 09 '23 at 23:46

3 Answers3

1

I had a test in my side, as you can see, I changed a style in MainLayout.razor.css and publish it to Azure web, it worked. I first published the origin app to Azure first then changed the style and published again.

enter image description here enter image description here

Tiny Wang
  • 10,423
  • 1
  • 11
  • 29
  • Yes - thank you - I have done an isolation test now to a new app slot and NONE of the scoped css works (all renders in plain text). I have updated the question with details - I think something is broken with scoped CSS itself in my app. – user18901997 Mar 09 '23 at 06:57
  • I found that my devops pipeline was not including ANY css - I'm updating this question with the solution shortly. – user18901997 Mar 09 '23 at 23:48
  • I publish my app manually and it worked. so it seems to relate to azure devops, I'm not familiar with that aspect... sorry for can't provide other ideas on your issue. – Tiny Wang Mar 10 '23 at 02:36
1

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)'

Shuryno
  • 532
  • 3
  • 13
  • 1
    This was it, it solved the problem. I’ve put exact details of what I changed (and why it wasn’t working) in my own pipeline on a separate answer. – user18901997 Mar 10 '23 at 20:40
0

It turns out that non-Development builds do not include the .css files in the output. I had to add a publish step to this and the PUBLISH artifact includes all of the resources as you'd expect:

New YAML:

    - task: UseDotNet@2
      displayName: Get .NET 7
      inputs:
       installationPath: $(Agent.ToolsDirectory)/dotnet
       packageType: sdk
       version: 7.x

    - task: DotNetCoreCLI@2
      displayName: Build
      inputs:
        command: build
        projects: $(workingDirectory)/*.csproj
        arguments: '--configuration $(buildConfiguration)'
    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        command: 'publish'
        publishWebProjects: false
        projects: $(workingDirectory)/*.csproj
        arguments: '--output $(build.artifactstagingdirectory) --configuration $(buildConfiguration)'
        zipAfterPublish: true

    - task: PublishPipelineArtifact@1
      inputs:
        fileSharePath: $(build.artifactstagingdirectory)
        ArtifactName: 'drop'
        publishLocation: pipeline

This runs the publish command directly to the same location the previous version did. I also had to make a minor update to the path that the deploy step was using to grab the zip package due to different folder structure of the output:

'$(Pipeline.Workspace)/drop/*.zip'

To this:

'$(Pipeline.Workspace)/drop/a/*.zip'

With the above changes the problem is solved.