Open
Description
@page "/counter-2"
@inject ILogger<Counter2> Logger
<PageTitle>Prerendered Counter 2</PageTitle>
<h1>Prerendered Counter 2</h1>
<p role="status">Current count: @CurrentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
[SupplyParameterFromPersistentComponentState]
public int? CurrentCount { get; set; }
protected override void OnInitialized()
{
CurrentCount ??= Random.Shared.Next(100);
Logger.LogInformation("CurrentCount set to {Count}", CurrentCount);
}
private void IncrementCount() => CurrentCount++;
}
CurrentCount set to 77
fail: Microsoft.AspNetCore.Components.Infrastructure.ComponentStatePersistenceManager[1000]
There was an error executing a callback while pausing the application.
System.ArgumentException: Cannot bind to the target method because its signature is not compatible with that of the delegate type.
at System.Reflection.RuntimeMethodInfo.CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags)
at Microsoft.AspNetCore.Components.Reflection.PropertyGetter..ctor(Type targetType, PropertyInfo property)
at Microsoft.AspNetCore.Components.SupplyParameterFromPersistentComponentStateValueProvider.PropertyGetterFactory(ValueTuple`2 key)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.AspNetCore.Components.SupplyParameterFromPersistentComponentStateValueProvider.ResolvePropertyGetter(Type type, String propertyName)
at Microsoft.AspNetCore.Components.SupplyParameterFromPersistentComponentStateValueProvider.<>c__DisplayClass11_0.<Subscribe>b__0()
at Microsoft.AspNetCore.Components.Infrastructure.ComponentStatePersistenceManager.<TryPauseAsync>g__TryExecuteCallback|18_0(Func`1 callback, ILogger`1 logger)
info: BlazorSample.Components.Pages.Counter2[0]
CurrentCount set to 43
The issue happens in https://github.com/dotnet/aspnetcore/blob/main/src/Components/Components/src/SupplyParameterFromPersistentComponentStateValueProvider.cs
In particular, on PropertyGetter constructor as it doesn't correctly handle value types.
https://github.com/dotnet/aspnetcore/blob/main/src/Components/Components/src/Reflection/PropertyGetter.cs#L10
We want to:
- Add unit tests in SupplyParameterFromPersistentComponentStateValueProviderTest that cover value types (like int, tuple, and nullable versions of those) that validate that we can serialize and deserialize the values.
- Validate that we get a failure in those cases.
- Change PropertyGetter constructor to fix the issue by correctly handling value types.