Blazor 8.0 SSR throws "System.InvalidOperationException: No converter registered for type" when model class contains a constructor with parameters
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
```csharp
@page "/"
Automatic Model Binding
@((MarkupString)_showMessage)
Please enter your name
Describe yourself
Hobby
Football
Basketball
Tennis
Is married?
@{ var idx = 0;}
@foreach(var val in new string[] { "USA", "Indonesia", "Egypt"})
{
var id = "nationality" + idx;
@val
idx++;
}
Submit
@code
{
[SupplyParameterFromForm(FormName = "info")] // matches FormName="info"
public Person PersonInfo { get; set; } = new();
string _showMessage = string.Empty;
void HandleSubmit()
{
_showMessage = $"Name: {PersonInfo.Name}
Description: {PersonInfo.Description}
Hobby: {PersonInfo.Hobby}
Is married: {PersonInfo.IsMarried}
Nationality: {PersonInfo.Nationality}
";
}
public class Person
{
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string Hobby { get; set; } = string.Empty;
public bool IsMarried { get; set; }
public string Nationality { get; set; } = string.Empty;
public Person()
{
}
public Person(string name)
{
Name = name;
}
}
}
```
will throw because `Person` class contains `public Person(string name)` constructor. If you remove it, it will work fine.
```
System.InvalidOperationException: No converter registered for type 'RazorFormHandlingTwo.Pages.Index+Person'.
at Microsoft.AspNetCore.Components.Endpoints.FormMapping.FormDataMapperOptions.CreateConverter(Type type, FormDataMapperOptions options)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd[TArg](TKey key, Func`3 valueFactory, TArg factoryArgument)
at Microsoft.AspNetCore.Components.Endpoints.HttpContextFormValueMapper.CanMap(Type valueType, String scopeName, String formName)
at Microsoft.AspNetCore.Components.CascadingParameterState.GetMatchingCascadingValueSupplier(CascadingParameterInfo& info, Renderer renderer, ComponentState componentState)
at Microsoft.AspNetCore.Components.CascadingParameterState.FindCascadingParameters(ComponentState componentState, Boolean& hasSingleDeliveryParameters)
at Microsoft.AspNetCore.Components.Rendering.ComponentState..ctor(Renderer renderer, Int32 componentId, IComponent component, ComponentState parentComponentState)
at Microsoft.AspNetCore.Components.Endpoints.EndpointComponentState..ctor(Renderer renderer, Int32 componentId, IComponent component, ComponentState parentComponentState)
at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.CreateComponentState(Int32 componentId, IComponent component, ComponentState parentComponentState)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.AttachAndInitComponent(IComponent component, Int32 parentComponentId)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame[] frames, Int32 frameIndex, Int32 parentComponentId)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
at Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderRootComponentAsync(Int32 componentId, ParameterView initialParameters)
at Microsoft.AspNetCore.Components.HtmlRendering.Infrastructure.StaticHtmlRenderer.BeginRenderingComponent(IComponent component, ParameterView initialParameters)
at Microsoft.AspNetCore.Components.Endpoints.EndpointHtmlRenderer.RenderEndpointComponent(HttpContext httpContext, Type rootComponentType, ParameterView parameters, Boolean waitForQuiescence) at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
at Microsoft.AspNetCore.Components.Endpoints.RazorComponentEndpointInvoker.RenderComponentCore(HttpContext context)
at Microsoft.AspNetCore.Components.Rendering.RendererSynchronizationContext.<>c.<b__10_0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Antiforgery.Internal.AntiforgeryMiddleware.InvokeAwaited(HttpContext context)
at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
```
### Expected Behavior
It should just work fine as input
### Steps To Reproduce
- Download this project https://github.com/dodyg/practical-aspnetcore/tree/net8.0/projects/blazor-ssr/RazorFormHandlingTwo
- Add a constructor with parameter to `Person` class.
- Run the project and submit.
### Exceptions (if any)
System.InvalidOperationException: No converter registered for type 'RazorFormHandlingTwo.Pages.Index+Person'
### .NET Version
8
### Anything else?
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.