The building of a rich user interface is not always easy for .NET
developers, especially if you dive deep to use React
, Angular
, webpack
and friends. Blazor
gives a nice trade-off bringing Razor
-like templates and C#
to a browser utilizing WebAssembly.
Blazor
is a free and open-source web framework that enables developers to create web apps usingC#
andHTML
. It is being developed byMicrosoft
— Wikipedia
Problem
Currently, I’m working with legacy projects, which cannot be easily ported to .NET Core
to make use of the newest technologies. However, it is possible to run Blazor WebAssembly
even in old-fashioned ASP.NET Web Forms
or ASP.NET MVC
and I’m going to show how. The following approach has been tested on production so it should work fine for you :)
Solution
As a starting point, I’m going to create ASP.NET MVC
project from one of the default templates. Here is it, our playground is ready and I call it OldAspNetApp
. For instance, About.cshtml
page looks like this:
@{
ViewBag.Title = "About";
}
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>
<p>Use this area to provide additional information.</p>
Let’s add Blazor WebAssembly
app now. The easiest way is to use blazorwasm
template for .NET Core
client, read more. Additionally, I added web.config that fits our needs. Basically, it is almost the same as what dotnet publish
produces. Our new Blazor
projects I called BlazorWasmApp
. As an example, About.razor
page is:
@page "/Home/About"
<div class="panel panel-primary">
<div class="panel-heading">
Blazor WASM app
</div>
<div class="panel-body">
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</div>
</div>
@code {
int currentCount = 0;
void IncrementCount()
{
currentCount++;
}
}
In order to reference BlazorWasmApp
to OldAspNetApp
I added Post-Build action for BlazorWasmApp.csproj
.
<Target Name="CopyToOldAspNetApp" AfterTargets="Build">
<Exec Command="xcopy $(TargetDir)web.config $(TargetDir)dist\_framework\ /Y" />
<Exec Command="xcopy $(TargetDir)dist $(SolutionDir)OldAspNetApp /Y /S" />
</Target>
It just copies all files BlazorWasmApp
project produces into OldAspNetApp
folder including web.config
.
To render Blazor
page in OldAspNetApp
I need only this:
<BlazorWasmApp>Blazor WASM app loading...</BlazorWasmApp>
<base href="/"/>
<script src="/_framework/blazor.webassembly.js"></script>
In order to reuse easily, I’m going to put these 3 lines into a shared partial view (BlazorWasmApp.cshtml
). As a result, About.cshtml
page of OldAspNetApp
becomes this:
@{
ViewBag.Title = "About";
}
@Html.Partial("BlazorWasmApp")
<h2>@ViewBag.Title.</h2>
<h3>@ViewBag.Message</h3>
<p>Use this area to provide additional information.</p>
By default, Blazor
app intercepts all clicks to prevent a full page reload. In my case, it breaks OldAspNetApp
so I disabled it here via overriding default implementation of INavigationInterception.
Finally, it is done. I have created the pull request for an easier understanding of what has been changed. Complete source code is in blazor-app branch of Gaev.BlazorOnAspNet
project.
Update as of 2023
Gaev.BlazorOnAspNet.sln
has been created using .NET Framework 4.5
which is too old in 2023. So, Gaev.BlazorOnAspNet_4_8.sln
using .NET Framework 4.8
is here.
Blazor 7
is the latest version as of May 2023. I have created pull request to show on how to use Blazor 7 WebAssembly
in ASP.NET Framework 4.8
app, check it out PR and branch.
As of 2023, Pitfalls section is no longer relevant, but I will keep it, just in case.
Pitfalls
Gaev.BlazorOnAspNet
solution should be opened by Visual Studio 2019
version 16.3+
. Before that specific version, you will get a compilation error, like the following. Most probably, Visual Studio 2017
will show the same error.
Error CS0246: The type or namespace name 'App' could not be found (are you missing a using directive or an assembly reference?)
Make sure .Net Core SDK 3.0+
is installed (via dotnet --info
).
I managed to find a workaround to open the solution by Visual Studio 2017
but it requires small changes. See the pull request. The source code is in vs2017-adaptation branch of Gaev.BlazorOnAspNet
project.