I have following Blazor component:
Button.razor
<button params...>
@ChildContent
</button>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
I want to use it in the Razor page. I know I can use:
@(await Html.RenderComponentAsync<Button>(RenderMode.ServerPrerendered))
for that.
But how do I pass the RenderFragment
parameter to this component? The RenderComponentAsunc
has a second argument where I can pass parameters for component so I think something like this
should be possible:
Page.cshtml
@(await Html.RenderComponentAsync<Button>(RenderMode.ServerPrerendered, new
{
ChildContent = "Button text"
}))
However this ends with error:
InvalidCastException: Unable to cast object of type 'System.String' to type 'Microsoft.AspNetCore.Components.RenderFragment'.
So I tried to pass RenderFragment
directly. I created extension method that create RenderFragment
from string:
public static class StringExtensions
{
public static RenderFragment ToRenderFragment(this string s) => b => b.AddContent(0, s);
}
And then render it this way:
@(await Html.RenderComponentAsync<Button>(RenderMode.ServerPrerendered, new
{
ChildContent = "Button text".ToRenderFragment()
}))
I wasn't successful with this approach either.
NotSupportedException: Serialization and deserialization of 'Microsoft.AspNetCore.Components.RenderFragment' instances are not supported.NotSupportedException: Serialization and deserialization of 'Microsoft.AspNetCore.Components.RenderFragment' instances are not supported.NotSupportedException: Serialization and deserialization of 'Microsoft.AspNetCore.Components.RenderFragment' instances are not supported.
The component can be also rendered with using <component>
tag. So I tried it.
<component type="typeof(Button)" render-mode="ServerPrerendered">
Button text
</component>
But this renders html incorrectly
<button></button>
Button text
And I want
<button>
Button text
</button>
How to do that? I am using button as simplied example here so direct use of markup in the .cshtml
file would be inconvenient duplication of code.
You could simply add a parameter of type
MarkupString
, which supports HTML content. In the blazor component you can just say@MyMarkupString
and it'll be rendered as HTML.If you do want to use the
RenderFragment
, you can use a normalstring
as parameter. Then in the component itself, you can call theToRenderFragment
on thatstring
, if it has a value.Both of these options should work around the
NotSupportedException
you got asstring
andMarkupString
are serializable.