dotnet / dotnet/aspnetcore

DynamicComponent Throws Run-Time Error on .NET 8

Open
#51,901 2 comments 2 reactions 1 assignee Assigned to @Copilot View on GitHub
area-blazor copilot-candidate enhancement feature-full-stack-web-ui Pillar: Complete Blazor Web Priority:1
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Describe the bug

When using the standard DynamicComponent (introduced in .NET 6) and specifying an instance-based @rendermode attribute ie.

```

```

The component throws a run-time error related to serialization:

```
An unhandled exception occurred while processing the request.
NotSupportedException: Serialization and deserialization of 'System.RuntimeType' instances is not supported.
System.Text.Json.Serialization.Converters.UnsupportedTypeConverter.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
I tried including only one DynamicComponent at a time and they still threw an exception. So specifying the rendermode on the instance does NOT work for dynamic components.
```

DynamicComponent expects a Type parameter which is of type System.RuntimeType - however in .NET 8 parameters must be serializable.

### Expected Behavior

DynamicComponent is widely used in Blazor applications to construct razor components dynamically based on type information. I would expect DynamicComponent to render a component in exactly the same manner as it does in .NET 6 and .NET 7.

### Steps To Reproduce

Please see repo: https://github.com/oqtane/OqtaneSSR which is based on the standard Blazor Web template in .NET 8 RC2. Set the appsettings.json Modules property to:

```
"Modules": [
{
"PagePath": "/",
"PageName": "Home",
"ThemeType": "OqtaneSSR.Components.Themes.MainLayout, OqtaneSSR",
"PaneName": "Default",
"ContainerType": "OqtaneSSR.Components.Containers.Container2, OqtaneSSR",
"ModuleType": "OqtaneSSR.Client.Components.Home, OqtaneSSR.Client",
"RenderMode": "InteractiveServer"
},
{
"PagePath": "/counter",
"PageName": "Counter",
"ThemeType": "OqtaneSSR.Components.Themes.MainLayout, OqtaneSSR",
"PaneName": "Default",
"ContainerType": "OqtaneSSR.Components.Containers.Container2, OqtaneSSR",
"ModuleType": "OqtaneSSR.Client.Components.Counter, OqtaneSSR.Client",
"RenderMode": "InteractiveServer"
},
{
"PagePath": "/weather",
"PageName": "Weather",
"ThemeType": "OqtaneSSR.Components.Themes.MainLayout, OqtaneSSR",
"PaneName": "Default",
"ContainerType": "OqtaneSSR.Components.Containers.Container2, OqtaneSSR",
"ModuleType": "OqtaneSSR.Client.Components.Weather, OqtaneSSR.Client",
"RenderMode": "InteractiveServer"
}
]
```

When you run the application, it will immediately throw a run-time error. This is caused by the line:

in OqtaneSSR\Components\Router\ModuleInstance2.razor

### Exceptions (if any)

An unhandled exception occurred while processing the request.
NotSupportedException: Serialization and deserialization of 'System.RuntimeType' instances is not supported.
System.Text.Json.Serialization.Converters.UnsupportedTypeConverter.Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)

### .NET Version

8.0.0-rc.2.23480.2

### Anything else?

A workaround to this problem is to create a custom component which accepts a TypeName (rather than a Type) and use RenderFragment to render it:

```
@DynamicComponent

@code {
[Parameter]
public string TypeName { get; set; }

RenderFragment DynamicComponent { get; set; }

protected override void OnParametersSet()
{
DynamicComponent = builder =>
{
builder.OpenComponent(0, Type.GetType(TypeName));
builder.CloseComponent();
};
}
}
```

Note that this workaround does not support Parameters - which is another problem with DynamicComponent as it uses a Dictionary for parameters.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.