If you opt to use an external library such as MudBlazor for your Blazor projects, and are using Visual Studio 2022, you may well discover that you’re missing any kind of intellisense for the bundled styles (that come with the library).

Taking MudBlazor specifically, it includes some handy utility classes for setting things like margins and padding.

The problem is, if you spin up a new MudBlazor project then start trying to use these classes in your Blazor components, you’ll be left guessing what’s available because there is no intellisense for them.

Take this code for example…

<div class="d-flex">
    <div class="blue white-text pa-4">a</div>
    <div class="flex-grow-1 red white-text pa-4">b</div>
</div>

Here we’re using classes such as pa-4 to set padding on all edges to 4 (which is actually 16px, if you’re interested)

Try to work on this code in VS2022 (at the time of writing) and you’ll have to make do without intellisense.

The Problem

Having explored this problem for a few hours it turns out to be a known limitation of the new Razor editor (which shipped with VS 2022).

When you use MudBlazor (or other libraries) you usually add them via a Nuget package.

You can then reference their static assets (CSS files, JavaScript etc) via a URL beginning with _content/

<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />

Under the hood, when you build your app (during development) .NET looks for a staticwebassets.runtime.json file in your project’s build output directory.

For example…

\bin\Debug\net6.0\<project>.staticwebassets.runtime.json

This JSON file then directs .NET to the location of any static assets referenced by the project.

In the case of a project which references MudBlazor, the mapping file will likely include an entry pointing to the Nuget Cache, like this one from my project:

“D:\.nuget\mudblazor\6.0.2\staticwebassets\”

When this project runs (during development) .NET will redirect all requests for MudBlazor CSS and JavaScript files to the Nuget cache (as per the location specified in the mapping file).

Note, this is only during development.

When you build your app for production the assets are rounded up and distributed as part of the published output.

Here’s the problem for intellisense in VS… The new razor editor does not yet have support for populating intellisense based on static assets linked from Nuget packages this way.

As confirmed by MS here:

https://github.com/dotnet/razor-tooling/issues/4590#issuecomment-1008907610

The workaround

So this is annoying. If you create your own stylesheets and put them in your project’s wwwroot folder you’ll get intellisense, but not if you use a package via NuGet (like MudBlazor).

It’s pretty safe to assume Microsoft will release an update which fixes this at some point, but in the meantime there is a workaround.

If you are able to take the files from the NuGet cache and copy them to your wwwroot folder, you might just be able to have your MudBlazor cake and eat it too! 🙂

Of course, you can do it manually; head to the Nuget cache, manually copy the files and paste them into wwwroot.

But then you’d have to do this every time you update MudBlazor, or clone your project to a new machine.

A better option is to integrate it into the build process.

Turns out that’s possible with a little help from MSBuild.

Here’s an MSBuild task you can add to your project’s .csproj file which automates the copying of the static files to wwwroot.

<Target Name="CollectMudBlazorStaticAssets" DependsOnTargets="ResolveStaticWebAssetsInputs" AfterTargets="Build" Condition=" '$(Configuration)' == 'Debug' ">
	<Copy SourceFiles="%(StaticWebAsset.Identity)" DestinationFolder="wwwroot/temp" Condition="$([System.String]::Copy(%(StaticWebAsset.Identity)).Contains('mudblazor'))" />
</Target>

It looks a bit weird (I mean, it is MSBuild after all, and if you don’t spend much time here it always seems a little alien) but this runs during development (not for production builds) and takes the output from a built-in task called ResolveStaticWebAssetsInputs

ResolveStaticWebAssetsInputs locates all static files for the project, and is a built-in Microsoft Task which runs as part of the usual build process.

The call to <Copy SourceFiles= … /> iterates over these static files, looking for any containing the word mudblazor, and copies them to the project’s wwwroot/temp folder.

With this in place, when you rebuild your project you’ll find MudBlazor’s static assets in wwwroot\temp and intellisense will spring into life.

A hack? Probably, but you’ll be glad you did!

I’m pretty sure this code falls into “hack” territory, and will almost certainly slow your development build down if you have lots of static assets…

But it makes intellisense work until Microsoft release something more official, so may just be worth adding to your project’s csproj file 🙂

Source code, step-by-step tutorials, videos and more

I've compiled a whole load of useful tutorials, source code for articles (like this one) and mini video series to help you push through all the noise and build better ASP.NET web applications, faster.

Drop your email in the box below to get new posts first, and instant access to 'the vault'.

I respect your email privacy. Unsubscribe with one click.

 

Next up

When to refactor a large Blazor component into separate, smaller ones?
Don’t rush to break your UI down into separate components (too soon)
How I organise my Blazor components
Consistency is key and make your components work harder to prove they’re actually the ‘same thing’
Sure, you could write all those Blazor HTTP calls yourself…
Writing boilerplate API client code is deadly dull and repetitive, Refit will do it for you