Blazor WebAssembly 3.2.0 Preview 1 release now available
Today we released a new preview update for Blazor WebAssembly with a bunch of great new features and improvements.
Here’s what’s new in this release:
- Version updated to 3.2
- Simplified startup
- Download size improvements
- Support for .NET SignalR client
Get started
To get started with Blazor WebAssembly 3.2.0 Preview 1 install the .NET Core 3.1 SDK and then run the following command:
dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1
That’s it! You can find additional docs and samples on https://blazor.net.
Upgrade an existing project
To upgrade an existing Blazor WebAssembly app from 3.1.0 Preview 4 to 3.2.0 Preview 1:
- Update all Microsoft.AspNetCore.Blazor.* package references to 3.2.0-preview1.20073.1.
- In Program.cs in the Blazor WebAssembly client project replace
BlazorWebAssemblyHost.CreateDefaultBuilder()
withWebAssemblyHostBuilder.CreateDefault()
. - Replace
IWebAssemblyHost
withWebAssemblyHost
. - Replace
IWebAssemblyHostBuilder
withWebAssemblyHostBuilder
. - Move the root component registrations in the Blazor WebAssembly client project from
Startup.Configure
to Program.cs by callingbuilder.RootComponents.Add<TComponent>(string selector)
. - Move the configured services in the Blazor WebAssembly client project from
Startup.ConfigureServices
to Program.cs by adding services to thebuilder.Services
collection. - Remove Startup.cs from the Blazor WebAssembly client project.
- If you’re hosting Blazor WebAssembly with ASP.NET Core, in your Server project replace the call to
app.UseClientSideBlazorFiles<Client.Startup>(...)
withapp.UseClientSideBlazorFiles<Client.Program>(...)
.
Version updated to 3.2
In this release we updated the versions of the Blazor WebAssembly packages to 3.2 to distinguish them from the recent .NET Core 3.1 Long Term Support (LTS) release. There is no corresponding .NET Core 3.2 release – the new 3.2 version applies only to Blazor WebAssembly. Blazor WebAssembly is currently based on .NET Core 3.1, but it doesn’t inherit the .NET Core 3.1 LTS status. Instead, the initial release of Blazor WebAssembly scheduled for May of this year will be a Current release, which “are supported for three months after a subsequent Current or LTS release” as described in the .NET Core support policy. The next planned release for Blazor WebAssembly after the 3.2 release in May will be with .NET 5. This means that once .NET 5 ships you’ll need to update your Blazor WebAssembly apps to .NET 5 to stay in support.
Simplified startup
We’ve simplified the startup and hosting APIs for Blazor WebAssembly in this release. Originally the startup and hosting APIs for Blazor WebAssembly were designed to mirror the patterns used by ASP.NET Core, but not all of the concepts were relevant. The updated APIs also enable some new scenarios.
Here’s what the new startup code in Program.cs looks like:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
await builder.Build().RunAsync();
}
}
Blazor WebAssembly apps now support async Main
methods for the app entry point.
To a create a default host builder, call WebAssemblyHostBuilder.CreateDefault()
. Root components and services are configured using the builder; a separate Startup
class is no longer needed.
The following example adds a WeatherService
so it’s available through dependency injection (DI):
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSingleton<WeatherService>();
builder.RootComponents.Add<App>("app");
await builder.Build().RunAsync();
}
}
Once the host is built, you can access services from the root DI scope before any components have been rendered. This can be useful if you need to run some initialization logic before anything is rendered:
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSingleton<WeatherService>();
builder.RootComponents.Add<App>("app");
var host = builder.Build();
var weatherService = host.Services.GetRequiredService<WeatherService>();
await weatherService.InitializeWeatherAsync();
await host.RunAsync();
}
}
The host also now provides a central configuration instance for the app. The configuration isn’t populated with any data by default, but you can populate it as required in your app.
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSingleton<WeatherService>();
builder.RootComponents.Add<App>("app");
var host = builder.Build();
var weatherService = host.Services.GetRequiredService<WeatherService>();
await weatherService.InitializeWeatherAsync(host.Configuration["WeatherServiceUrl"]);
await host.RunAsync();
}
}
Download size improvements
Blazor WebAssembly apps run the .NET IL linker on every build to trim unused code from the app. In previous releases only the core framework libraries were trimmed. Starting with this release the Blazor framework assemblies are trimmed as well resulting in a modest size reduction of about 100 KB transferred. As before, if you ever need to turn off linking, add the <BlazorLinkOnBuild>false</BlazorLinkOnBuild>
property to your project file.
Support for the .NET SignalR client
You can now use SignalR from your Blazor WebAssembly apps using the .NET SignalR client.
To give SignalR a try from your Blazor WebAssembly app:
-
Create an ASP.NET Core hosted Blazor WebAssembly app.
dotnet new blazorwasm -ho -o BlazorSignalRApp
-
Add the ASP.NET Core SignalR Client package to the Client project.
cd BlazorSignalRApp dotnet add Client package Microsoft.AspNetCore.SignalR.Client
-
In the Server project, add the following Hub/ChatHub.cs class.
using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; namespace BlazorSignalRApp.Server.Hubs { public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, message); } } }
-
In the Server project, add the SignalR services in the
Startup.ConfigureServices
method.services.AddSignalR();
-
Also add an endpoint for the
ChatHub
inStartup.Configure
..UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); endpoints.MapHub<ChatHub>("/chatHub"); endpoints.MapFallbackToClientSideBlazor<Client.Program>("index.html"); });
-
Update Pages/Index.razor in the Client project with the following markup.
@using Microsoft.AspNetCore.SignalR.Client @page "/" @inject NavigationManager NavigationManager <div> <label for="userInput">User:</label> <input id="userInput" @bind="userInput" /> </div> <div class="form-group"> <label for="messageInput">Message:</label> <input id="messageInput" @bind="messageInput" /> </div> <button @onclick="Send" disabled="@(!IsConnected)">Send Message</button> <hr /> <ul id="messagesList"> @foreach (var message in messages) { <li>@message</li> } </ul> @code { HubConnection hubConnection; List<string> messages = new List<string>(); string userInput; string messageInput; protected override async Task OnInitializedAsync() { hubConnection = new HubConnectionBuilder() .WithUrl(NavigationManager.ToAbsoluteUri("/chatHub")) .Build(); hubConnection.On<string, string>("ReceiveMessage", (user, message) => { var encodedMsg = user + " says " + message; messages.Add(encodedMsg); StateHasChanged(); }); await hubConnection.StartAsync(); } Task Send() => hubConnection.SendAsync("SendMessage", userInput, messageInput); public bool IsConnected => hubConnection.State == HubConnectionState.Connected; }
-
Build and run the Server project
cd Server dotnet run
-
Open the app in two separate browser tabs to chat in real time over SignalR.
Known issues
Below is the list of known issues with this release that will get addressed in a future update.
-
Running a new ASP.NET Core hosted Blazor WebAssembly app from the command-line results in the warning:
CSC : warning CS8034: Unable to load Analyzer assembly C:\Users\user\.nuget\packages\microsoft.aspnetcore.components.analyzers\3.1.0\analyzers\dotnet\cs\Microsoft.AspNetCore.Components.Analyzers.dll : Assembly with same name is already loaded.
- Workaround: This warning can be ignored or suppressed using the
<DisableImplicitComponentsAnalyzers>true</DisableImplicitComponentsAnalyzers>
MSBuild property.
- Workaround: This warning can be ignored or suppressed using the
Feedback
We hope you enjoy the new features in this preview release of Blazor WebAssembly! Please let us know what you think by filing issues on GitHub.
Thanks for trying out Blazor!
108 comments
Hi Dan,
dotnet –list-sdk
3.1.101 [C:\Program Files\dotnet\sdk]
3.1.200-preview-014883 [C:\Program Files\dotnet\sdk]
How do I get 3.1.200-preview-014883 version of the sdk on a Linux machine? I can’t find the download link. I think VS Preview installed for me on Windows.
Thanks.
The .NET Core SDK updates with VS. Each VS preview release typically contains a preview build of the .NET Core SDK. These builds aren’t typically generally available for download until there is a stable version. But you might be able to find the latest 3.1.200 nightly builds here: https://github.com/dotnet/core-sdk.
I did not and an app with PWA occurs with error:
‘MainLayout’ could not be found (are you missing a using directive or an assembly reference.
While another App is ok.
Hi Jefferson,
It sounds like the compiler can’t find the MainLayout component type. This may be because it failed to build, or it may be in a namespace or assembly that isn’t property referenced. Check your build output and see if there were any other build errors.
I hope this helps!
Daniel Roth
Thanks, but after updated, when I run an app I got this error.
actually, also
for *.dll.config files of my own libraries (also updated).
Any clue?
Environment
Microsoft Visual Studio Enterprise 2019, Version 16.4.2
It looks like some of the files couldn’t be download. Are the requested files not present?
Exactly, but not sure why.
For instance this file is in the output:
and its request _framework/_bin/Blorc.Core.dll.config just failed.
The repo is here > https://github.com/WildGums/Blorc.Core.
I don’t think there’s anything in Blazor WebAssembly by default that will make .dll.config files available over the network. Is the request for this file expected? Or is the existence of this request the problem?
>> I don’t think there’s anything in Blazor WebAssembly by default that will make .dll.config files available over the network.
Agree, the config files are listed in the output:
>>Is the request for this file expected?
I don’t request that file explicitly. By default, when the application is launched the file is requested.
>>Or is the existence of this request the problem?
The file exists, so its existence is not a problem. The problem right after of the request of such file failed, because I got this error.
Thanks Daniel. Looks like I have a custom msbuild configuration that is breaking something.
I updated a Server Hosted WebAssembly app to 3.2 preview this afternoon and it runs great in visual studio. But when I deploy it to IIS it never gets past my wwwroot/index.html app section loading message. Here is my Program.cs Main from the client-side:
<
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>(“app”);
builder.Services.AddOptions();
builder.Services.AddBlazoredModal();
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<AuthenticationStateProvider, ApiAuthenticationStateProvider>();
builder.Services.AddScoped<IAuthService, AuthService>();
await builder.Build().RunAsync();
}
Pre-conversion repo at: https://github.com/drsinder/Notes2021Blazor
Any errors in the browser dev console?
Yes. Two. This one looks most promising:
19:03:08.381 ReferenceError: Module is not defined blazor.webassembly.js:1:34204
Visual studio is failing to produce the clients: blazor.boot.json and the entire _bin folder. I copied in from the clients Client\bin\Release\netstandard2.1\dist_framework and the app works.
I had to copy all the files to a new solution to get it to work.
Hi Dan,
In “Support for the .NET SignalR client” sections 4 and 5 you refer to the Startup class. I thought that was gone now?
/Mikael
We no longer have a Startup class in Blazor WebAssembly client projects, but the Startup class still used for ASP.NET Core projects. In the steps above, the Startup class in in the ASP.NET Core Server project that is hosting the Blazor WebAssembly client project.
Signalr and chat
Have anyone managed to try this chat logic in this example? I have, it works when running from within visual studio, cool.. but when i publish to azure webapp it doesnt work. I have enabled web sockets on the webapp. Any other clues?
Do any errors show up in the browser console or network trace?
I built a request bin as my first Blazor project to try this support for the .NET SignalR client and it works amazingly. Thanks a lot.
https://blazorbin.azurewebsites.net/
Dear daniel,
I update to the last release with following code on Program.cs:
But I retrieve following error:
blazor.webassembly.js:1 WASM: Unhandled exception rendering component:
l.printErr @ blazor.webassembly.js:1
blazor.webassembly.js:1 WASM: System.InvalidOperationException: Unable to resolve service for type ‘Microsoft.Extensions.Options.IOptions1[Microsoft.AspNetCore.Authorization.AuthorizationOptions]’ while attempting to activate ‘Microsoft.AspNetCore.Authorization.DefaultAuthorizationPolicyProvider’.
l.printErr @ blazor.webassembly.js:1
……..following….
Where I need to fix ?
Hi,
I solved for myself only needed to add following row on builder:
using the latest preview version, i’m trying to add an onclick button to pass a parameter and do an async call but always get the following error:
(in error list window): CS1660 Cannot convert lambda expression to type ‘object‘ because it is not a delegate type
(in output window): error CS1660: Cannot convert lambda expression to type ‘bool‘ because it is not a delegate type
no matter what i try i always get compile error. Here is a sample razor page to replicate.
Try
Authorized SignalR hubs is not working properly:
_connection = new HubConnectionBuilder().WithUrl(
.WithUrl(NavigationManager.ToAbsoluteUri(“/chatHub”)),
opt =>
{
opt.AccessTokenProvider = async () => (await UserManager.GetUserAsync()).AccessToken;
})
.Build();
Here is the error:
Workaround:
Set Transports to
LongPolling
_connection = new HubConnectionBuilder().WithUrl(
.WithUrl(NavigationManager.ToAbsoluteUri(“/chatHub”)),
opt =>
{
opt.Transports = HttpTransportType.LongPolling;
opt.AccessTokenProvider = async () => (await UserManager.GetUserAsync()).AccessToken;
})
.Build();
Yes, there is an issue with trying to setup authentication with the .NET SignalR client in a Blazor WebAssembly app. It’s being tracked by https://github.com/dotnet/aspnetcore/issues/18697.