-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Description
Is there an existing issue for this?
- 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.
<DynamicComponent Type="@_type" @rendermode="RenderMode.InteractiveServer">
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<T>.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:
<DynamicComponent Type="@_type" @rendermode="RenderMode.InteractiveServer">
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.