dotnet / dotnet/aspnetcore

Blazor 8.0 SSR throws "System.InvalidOperationException: No converter registered for type" when model class contains a constructor with parameters

Open
#55,711 5 comments 1 reaction 0 assignees View on GitHub
area-blazor enhancement feature-model-binding Pillar: Dev Experience triaged
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

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.