aspnetcore
aspnetcore copied to clipboard
Blazor WebAssemblyHostBuilder initialization fails if root component's assembly is not loaded on client startup
Describe the bug
Blazor WebAssembly (5.0-rc1) client project startup fails when prerendering is used and the root component is defined in a razor class library, unless the client project's Main method explicitly references the razor class library assembly.
This appears to be the case because WebAssemblyHostBuilder.CreateDefault(...) only searches loaded assemblies for the root component type specified in the <component>
tag in the server-side host page. It is not sufficient for the client project to reference the razor class library project. The client's Main method must explicitly cause the razor class library assembly to load before WebAssemblyHostBuilder.CreateDefault(...) is called.
I understand that most Blazor WebAssembly apps will define their root component in the client-side entry assembly, but it is sometimes convenient to define all of a Blazor app's UI components, including the root component, in a class library project that can be used in both Blazor Server and Blazor WebAssembly apps. While the client initialization error can be worked around, the workaround is not obvious and the error message (see below) is unhelpful.
To Reproduce
See repro project at https://github.com/tehaucave/RootComponentFromClassLibrary
This is a standard ASP.NET Core-hosted Blazor WebAssembly (5.0-rc1) solution with all components removed from the client project, and a razor class library project added containing a single razor component named AppRoot. Also, index.html has been removed from the client project and a _Host.cshtml page has been added to the server project and configured as the server's fallback page. A <component>
tag is included in _Host.cshtml with type=AppRoot and render-mode=WebAssemblyPrerendered. In the client's Program.Main method, the explicit root component registration has been removed.
The client app throws a runtime exception on startup unless I add code like the following before the call to WebAssemblyHostBuilder.CreateDefault(args):
typeof(AppRoot).ToString()
Exceptions (if any)
From browser console (chrome):
blazor.webassembly.js:1 System.ArgumentNullException: Value cannot be null. (Parameter 'componentType') at Microsoft.AspNetCore.Components.WebAssembly.Hosting.RootComponentMappingCollection.Add(Type componentType, String selector, ParameterView parameters) at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostBuilder.InitializeRegisteredRootComponents(WebAssemblyJSRuntimeInvoker jsRuntimeInvoker) at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostBuilder..ctor(WebAssemblyJSRuntimeInvoker jsRuntimeInvoker) at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostBuilder.CreateDefault(String[] args) at RootComponentFromClassLibrary.Client.Program.Main(String[] args) in C:\Users\a060514\source\repos\github\RootComponentFromClassLibrary\Client\Program.cs:line 25 at Microsoft.AspNetCore.Components.WebAssembly.Hosting.EntrypointInvoker.InvokeEntrypoint(String assemblyName, String[] args)
Further technical details
-
ASP.NET Core version 5.0-rc1
-
Visual Studio 2019 16.8.0 Preview 3.2
-
Include the output of
dotnet --info
.NET SDK (reflecting any global.json): Version: 5.0.100-rc.1.20452.10 Commit: 473d1b592e
Runtime Environment: OS Name: Windows OS Version: 10.0.18362 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.100-rc.1.20452.10\
Host (useful for support): Version: 5.0.0-rc.1.20451.14 Commit: 38017c3935
.NET SDKs installed: 3.1.100 [C:\Program Files\dotnet\sdk] 3.1.300-preview-015048 [C:\Program Files\dotnet\sdk] 3.1.300 [C:\Program Files\dotnet\sdk] 3.1.400-preview-015178 [C:\Program Files\dotnet\sdk] 3.1.401 [C:\Program Files\dotnet\sdk] 5.0.100-preview.8.20417.9 [C:\Program Files\dotnet\sdk] 5.0.100-rc.1.20452.10 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-preview.8.20414.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.0-rc.1.20451.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-preview.8.20407.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.0-rc.1.20451.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-preview.8.20411.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.0-rc.1.20452.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs: https://aka.ms/dotnet-download
- The IDE (VS / VS Code/ VS4Mac) you're running on, and it's version
Thanks for contacting us.
We're moving this issue to the Next sprint planning
milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Just encountered the same issue :(
Same issue because of tree shaking, while trying to use a WebAssemblyPrerendered content from a RCL project. The workaround for this problem: Just write a reference to your component type in your WASM Main method before calling RunAsyc.
Like:
using BlazorDynamicEngine.Client;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
namespace Company.WebApplication1
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
//JUST DO A STATIC REFERENCE HERE !
var type = typeof(BlazorDynamicEngine.App.App);
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}
}
}
Also just hit this, using base app class from an RCL. Workaround was to flex a type in the RCL assembly as previous posters highlighted. Unlike @Daddoon , we found we had to do it explicitly BEFORE the line
var builder = WebAssemblyHostBuilder.CreateDefault()
i.e.
AssemblyRegister.GetAssemblies(); // <- our own helper which knows about assemblies at compile time
var builder = WebAssemblyHostBuilder.CreateDefault()
...
Also just hit this, using base app class from an RCL. Workaround was to flex a type in the RCL assembly as previous posters highlighted. Unlike @Daddoon , we found we had to do it explicitly BEFORE the line
var builder = WebAssemblyHostBuilder.CreateDefault()
i.e.
AssemblyRegister.GetAssemblies(); // <- our own helper which knows about assemblies at compile time var builder = WebAssemblyHostBuilder.CreateDefault() ...
Indeed, i found later on another project that sometime, the linker seem to optimize agressively, and so my workaround was not always working.
On my side, using a ReferenceConverter object before creating the WebAssemblyHostBuilder did the trick. Possibly, it just do the same as you @mstancombe , but just posting an example of code if useful to someone else:
using BlazorDynamicEngine.Client;
using BlazorDynamicEngine.Client.Extensions;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using System.ComponentModel;
namespace Company.WebApplication1
{
public class Program
{
private ReferenceConverter ReferenceConverter = new ReferenceConverter(typeof(BlazorDynamicEngine.App.App));
public static async Task Main(string[] args)
{
ReferenceConverter test = new ReferenceConverter(typeof(BlazorDynamicEngine.App.App));
var builder = WebAssemblyHostBuilder.CreateDefault(args);
/* Custom code here... */
await builder.Build().RunAsync();
}
}
}
Thanks for contacting us.
We're moving this issue to the .NET 8 Planning
milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
Thanks for contacting us.
We're moving this issue to the .NET 9 Planning
milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.
Same on .NET Core 8 WebAssembly project.
It was crashing on following line in the Program.cs file:
var builder = WebAssemblyHostBuilder.CreateDefault(args);
Just put some valid json into wwwroot/appsettings.json
For example:
{ }
or
{ "MySettingValue":1 }
Using .NET Aspire causes this issue but everything works fine now without Aspire. It should be consistent.
Still the same issue with SDK 8.0.100