Using Blazor Wasm with .NET Framework MVC or another old/external site

Santiago Cattaneo
5 min readJul 12, 2021

--

Blazor Wasm is cool, I like coding web components in c#. Blazor WebAssembly Apps works great as static pages and it’s integrated very well with ASP.NET (Core/5/6 preview 5 for this examples).

But, what if I want to use all those components on the old c# stuff like Net Framework 4.x or inclusive over non c# platforms?

A little research

First at all I needed to understand the routing logic. When you create a Blazor Wasm Project with .NET 6 you get a bunch of files, we are interested in:

From Program.cs, this lines:

program.cs rootcomponent definition

From Index.html, this lines:

The Root component we are registering is replaced by the div with the same Id, the default project App component have a Router component wich is part of Blazor and allow us to route to our Blazor Page components.

If you change the Router component for a standard component, like the famous counter, the page that will contain the div with the #app id will show it without the navigation/routing part.

So, my first (failed) try was to register multiple “RootComponents” with one id for every component I want to use on my old site:

It compiles ok, and works ok but only if the index.html have all the ids defined, if there is one missing you will get an exception. That isn’t the behavior I wanted.

My second approach was to keep Program.cs and the App as they were initially created and then in the Page folder modify the @page directive with the pages I have in my old .NET framework MVC project. Let’s suppose we want to add a component in the /Home/Contact page on the old site, we need to create a Blazor Page component with that same path.

This way works great, I only registered one Root component but the components I want to display in different routes must match with the page directive.

The problem with this approach is that Blazor intercept the click on anchors, and try to resolve internally in the Blazor “app” to do the routing, we don’t want that, we want the normal flow of our old MVC app reloading the whole page.

To do that we need to disable the navigation:

You can see this example in elgransan/BlazorWasmWithNetFrameworkMVC at firstOption (github.com)

The final approach, because I don’t want to keep in sync the Blazor routes with my MVC routes, with a little hack using a javascript function and a Dynamic component you can use the component you want in the page you want.

You must change the Router component in the App component for this:

What I’m doing here is to get from the div a “component” property witch tell us the name of the component we want to render.

On our MVC pages we need to create a javascript function to get the “component” property from the App div as you can see in the figure above.

Also you must add the _framework script and the base tag.

The steps from scratch

Ok, let’s go coding

  1. Create 2 projects on one solution:

ASP.NET Framework MVC and Blazor Wasm (without ASP.NET Core) in Visual Studio

2. Create a shared razor page (/Views/Shared) on the ASP.NET Framework MVC project like this:

3. Add somewhere in the /Home/Index.cshtml a reference to the previous file and the div with the property “component”

@Html.Partial(“Blazor”)

<div id=”app” component=”BlazorApp.Pages.Counter”>Loading…</div>

4. We need to tell IIS (this is a configuration issue with IIS dealing with some file types but maybe could be a issue too with another webservers) we want to accept this file types (those Blazor wasm use on the client)

<system.webServer>
<staticContent>
<remove fileExtension=”.dat” />
<remove fileExtension=”.dll” />
<remove fileExtension=”.wasm” />
<remove fileExtension=”.blat” />
<remove fileExtension=”.pdb” />
<mimeMap fileExtension=”.dat” mimeType=”application/octet-stream” />
<mimeMap fileExtension=”.dll” mimeType=”application/octet-stream” />
<mimeMap fileExtension=”.wasm” mimeType=”application/wasm” />
<mimeMap fileExtension=”.blat” mimeType=”application/octet-stream” />
<mimeMap fileExtension=”.pdb” mimeType=”application/octet-stream” />
</staticContent>
</system.webServer>

5.Enaugh with the old stuff, now go to the Blazor Wasm Project and modify the App.razor for this:

@inject IJSRuntime JS

<DynamicComponent Type=”@Type.GetType(component)” />

@code {

private string component = “”;

public override async Task SetParametersAsync(ParameterView parameters)

{

component = await JS.InvokeAsync<string>(“getProperty”, “app”, “component”);

await base.SetParametersAsync(parameters);

}

}

6. Last but no least is to copy the Blazor wasm build (only the _framework folder) to the old proyect with a post-build xcopy:

Note: I tried to put the _framework inside the “Content” folder but I couln’t figure out how, let me know if you can.

That’s all, I added some other stuff to the repo witch allow us to debug the components stand-alone way, you can see it below:

I added a STANDALONE configuration on the Blazor wasm project you can run for debugging/testing, with that configuration you can use the default navigation and test all the components, also the files aren’t copied to the MVC project.

Super cool

You can see this solution in elgransan/BlazorWasmWithNetFrameworkMVC at secondOption (github.com)

Summary

Although it’s posible to use Blazor components on our old sites, still there isn’t a direct way to do it, maybe in future releases this will be straighforward.

Cheers!

--

--