-
Notifications
You must be signed in to change notification settings - Fork 10.3k
A published blazor wasm app throws a serialization error "Unhandled exception rendering component: ConstructorContainsNullParameterNames" #52947
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm getting the identical exception, also in a published WASM app serializing a KeyValue pair. Error does not happen locally. In my case this is the Telerik blazor grid serializing or deserializing a KeyValue pair under the hood that is related to a default date filter in the grid. As a result this error appears on any grid that has a filterable date column. |
@Stamo-Gochev has this ever worked in a previous version of Blazor? What I suspect is happening is that the KeyValuePair is being linked out. That's because the constructor and other elements are not being preserved. It works with an anonymous type because that type is created within the app assembly and Blazor doesn't serialize that. If the members are used elsewhere in the app, the issue will go away, but seems that they are only being used during serialization. You can use https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trimming-options?pivots=dotnet-8-0#root-descriptors and https://github.com/dotnet/runtime/blob/main/docs/tools/illink/data-formats.md#descriptor-format to teach the linker not to strip away members from the type. If you are still running into issues after taking those steps, let us know, it might be a different linker issue. |
@javiercn I have an application that began exhibiting this problem upon upgrading to .NET 8. I didn’t do too much research as I figured you all would hash this bug out, but if you’re under the impression this is not a new issue/not planning to be addressed soon I can also do more digging. |
Hi @Stamo-Gochev. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time. |
@taylorchasewhite If the issue happens at the linking stage, there are two possibilities:
In most situations, the member is simply not being preserved, and that matters most when you are using types from the framework, since gestures that you might expect will result in them being preserved (like being passed to a JS interop call) won't actually do so. In those situations, the descriptor file is the way to go. |
Yes it has, I tested it on the same exact project just with different targets, on .NET 7 it works fine, but on .NET 8 an exception occurs out.mp4here's the project repo: https://github.com/SaifAqqad/blazor-bug-test Imo even if this is the intended behavior of the trimmer, there should be a built-in exclusion of certain types (serialization, etc) for wasm projects |
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate. See our Issue Management Policies for more information. |
Yes, it works with previous versions - .NET 6.0 and .NET 7.0. The Home.razor page and the JS file can be pasted in a standalone .NET 6.0 and .NET 7.0 projects for comparison. Regarding the suggestions:
this is possible, but the change in the behavior looks more or less like a regression to me - it is not clear why As .NET 8.0 is a major release, I can accept a public issue that states that |
This seems to be a regression in the linker in fact. |
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsIs there an existing issue for this?
Describe the bugAn error is thrown when making a JS interop call in a published blazor wasm app that should serialize a This seems to be related to trimming as running this with things like In addition, using an anonymous type instead of
Expected BehaviorNo error is thrown. Steps To Reproduce
Exceptions (if any)Exceptionblazor.web.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: ConstructorContainsNullParameterNames, System.Collections.Generic.KeyValuePair`2[System.String,System.String] SerializationNotSupportedParentType, System.Object Path: $.
System.NotSupportedException: ConstructorContainsNullParameterNames, System.Collections.Generic.KeyValuePair`2[System.String,System.String] SerializationNotSupportedParentType, System.Object Path: $.
---> System.NotSupportedException: ConstructorContainsNullParameterNames, System.Collections.Generic.KeyValuePair`2[System.String,System.String]
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_ConstructorContainsNullParameterNames(Type )
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.PopulateParameterInfoValues(JsonTypeInfo )
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreateTypeInfoCore(Type , JsonConverter , JsonSerializerOptions )
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.CreateJsonTypeInfo(Type , JsonSerializerOptions )
at System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver.GetTypeInfo(Type , JsonSerializerOptions )
at System.Text.Json.JsonSerializerOptions.GetTypeInfoNoCaching(Type )
at System.Text.Json.JsonSerializerOptions.CachingContext.CreateCacheEntry(Type type, CachingContext context)
--- End of stack trace from previous location ---
at System.Text.Json.JsonSerializerOptions.CachingContext.CacheEntry.GetResult()
at System.Text.Json.JsonSerializerOptions.CachingContext.GetOrAddTypeInfo(Type , Boolean )
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type , Boolean , Nullable`1 , Boolean , Boolean )
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.Configure()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.<EnsureConfigured>g__ConfigureSynchronized|172_0()
at System.Text.Json.Serialization.Metadata.JsonTypeInfo.EnsureConfigured()
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type , Boolean , Nullable`1 , Boolean , Boolean )
at System.Text.Json.WriteStackFrame.InitializePolymorphicReEntry(Type , JsonSerializerOptions )
at System.Text.Json.Serialization.JsonConverter.ResolvePolymorphicConverter(Object , JsonTypeInfo , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.Converters.DictionaryOfTKeyTValueConverter`3[[System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnWriteResume(Utf8JsonWriter , Dictionary`2 , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonDictionaryConverter`3[[System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryWrite(Utf8JsonWriter , Dictionary`2 , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Dictionary`2& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWriteAsObject(Utf8JsonWriter , Object , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.Converters.ArrayConverter`2[[System.Object[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnWriteResume(Utf8JsonWriter , Object[] , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonCollectionConverter`2[[System.Object[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnTryWrite(Utf8JsonWriter , Object[] , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TryWrite(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].WriteCore(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
Exception_EndOfInnerExceptionStack
at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& , NotSupportedException )
at System.Text.Json.Serialization.JsonConverter`1[[System.Object[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].WriteCore(Utf8JsonWriter , Object[]& , JsonSerializerOptions , WriteStack& )
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1[[System.Object[], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Serialize(Utf8JsonWriter , Object[]& , Object )
at System.Text.Json.JsonSerializer.WriteString[Object[]](Object[]& , JsonTypeInfo`1 )
at System.Text.Json.JsonSerializer.Serialize[Object[]](Object[] , JsonSerializerOptions )
at Microsoft.JSInterop.JSRuntime.InvokeAsync[IJSVoidResult](Int64 , String , CancellationToken , Object[] )
at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[Microsoft.JSInterop.Infrastructure.IJSVoidResult, Microsoft.JSInterop, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime , String , Object[] )
at BlazorissueWasmSerialization.Client.Pages.Home.OnButtonShowIssueClick()
at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task , ComponentState )
.NET Version8.0.100 Anything else?No response
|
Duplicate of dotnet/runtime#74141, dotnet/runtime#94806 and dotnet/runtime#81709. The reason this error shows up on serialization traces as well as deserialization is because of this breaking change. I would recommend either switching to the source generator or applying a |
Does this mean that system.text.json doesn't support de/serializing I still think this should be looked into more, especially for built-in types like KeyValuePair.
How is it acceptable that serializing such simple types would need this special handling, it sounds like a nightmare tbh. Throwing attributes around as a fix for such things is not acceptable imo. |
No. It means that using reflection-based serialization in trimmed applications is not reliable and can result in multiple failures like the one reported here. This is a problem inherent to using dynamic member access via reflection in trimmed applications and there's not much that can be done about it other than adding manual annotations to work around the issues that pop up. Our recommendation is to switch to the source generator if you must use a trimmed app, see this article for more details. |
@eiriktsarpalis I have same problem after upgrade to .Net 8. As you explained, we need to handle this problem by changing our code, and .Net will not support anymore like previous .Net 7 version? |
@SaifAqqad @Stamo-Gochev any work around for this matter? I have same problem! Thanks! |
@hoangdovan The fundamental issue is that trimming and reflection are fundamentally incompatible. There's nothing that we can do about this in the System.Text.Json layer other than recommend switching to the source generator which is trimming-safe. |
It still requires changing your code though and whether you need to serialize a One option is to create a custom serializer, another one is to map it to something like: someKeyValuePair.Select(x => new { key = x.Key, value = x.Value })... which follows the structure of a JSON-serialized |
@Stamo-Gochev Thank you. In my case, I create a custom class replace for .Net KeyPairValue to fix this error! |
8.0.6 still there
|
source of exception:
|
Yeap confirmed tuple is getting the same error only on WASM |
Current workaround is to set |
Why wait for a fix that might not make it into .NET 8 at all? Here's a laughably simple workaround if you turn off trimming. Just replace
|
FWIW the issue still persists with the release of VS 2022 (17.12) and .NET 9 |
This is very anecdotal but it only added 1MB to my 40MB app. |
Removing milestone for servicing triage. |
Recently upgraded Blazor WASM app from .NET 6 to .NET 8, and my Published app throws this exception, in relation to Tuple serialization. Please consider a fix for this in .NET 8. Implemented following in project file to workaround this temporarily: |
@maraf please verify we don't need to do more but I think dotnet/runtime#112216 should get most of this? |
@lewing @maraf ... @pavelsavara and I were just working on a doc section related to the file descriptor approach with a .NET 9 BWA (per-component) project. It's breaking 💥. The test project is at ... https://github.com/guardrex/BlazorTrimmerTesting ... and when the component is hit, the ...
... error is thrown. The docs PR will keep the guidance commented out until it's resolved in the framework. Until then, we'll just have the |
Here i am too 🙋♂️, i've got crashed into that after an upgrade from .net 5 to dotnet 8 😁 workaround will be applied for sure. |
UPDATE on documentation: Pavel and I worked out that the file descriptor approach is going to need to wait for coverage until at least the release of .NET 10. For now, our current guidance on this scenario is at ... If the file descriptor approach lights up at .NET 10, we're going to activate that coverage in the article for >=10.0 and remove the last section on using custom types, saying that you can use a custom type but that we don't recommend it. Currently, the best approach is the dynamic dependency approach. For a At the top of the component definition file ... @using System.Diagnostics.CodeAnalysis In the [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(KeyValuePair<string, string>))]
private List<KeyValuePair<string, string>> items = []; |
That's good documentation Luke. Would it be possible to include that link in the exception message string resource in a similar fashion that's done for the <data name="ConstructorContainsNullParameterNames" xml:space="preserve">
<value>
The deserialization constructor for type '{0}' contains parameters with null names.
This might happen because the parameter names have been trimmed by ILLink.
Consider using the source generated serializer instead
(see https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/configure-trimmer#failure-to-preserve-types-used-by-a-published-app).
</value>
</data> |
@mguinness ... Thanks. That's up the product unit engineers here. I only control the article side of things. We don't want silly green dinosaurs 🦖 mess'in about in the framework code! 😆 |
Uh oh!
There was an error while loading. Please reload this page.
Is there an existing issue for this?
Describe the bug
An error is thrown when making a JS interop call in a published blazor wasm app that should serialize a
KeyValuePair
value.This seems to be related to trimming as running this with things like
dotnet run --configuration Release
works as expected, but publishing the app starts the trimmer by default.In addition, using an anonymous type instead of
KeyValuePair
works without any errors.Note
I tried to disable the trimming, but the error is still present. Any suggestions on how to do that will be helpful - this might turn out to be another issue though.
Expected Behavior
No error is thrown.
Steps To Reproduce
dotnet publish --configuration Release
BlazorissueWasmSerialization/BlazorissueWasmSerialization/bin/Release/net8.0/publish
dotnet BlazorissueWasmSerialization.dll
Exceptions (if any)
Exception
.NET Version
8.0.100
Anything else?
No response
The text was updated successfully, but these errors were encountered: