-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
System.Text.Json deserialize fails on List<Tuple<,>> with trimming #73169
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsDescriptionClass:
fails to deserialize when published as self contained and trim mode link. (linux-arm, I haven't tried other platforms). When using trim mode CopyUsed - everything works, but my app is almost 50% bigger. json example:
Reproduction Stepssmall example compiled as self contained and
Expected behaviorTo deserialize json. Actual behaviorException:
Regression?Yes. It was working in NET5. After installing NET6 it doesn't work in NET5. Net6 linker is used to compile NET5 project? Known WorkaroundsUse TrimMode=CopyUsed Configuration-r linux-arm -p:PublishTrimmed=True -p:TrimMode=CopyUsed --self-contained true -c Release -f net6.0 Other informationNo response
|
Stacktrace appears related to #58690. |
@michaldobrodenka did your app produce trim warnings when you were linking? |
Yes, the trimming is done by the SDK. It uses compatible settings, but the underlying trimming optimizations can be different. If this is indeed the same issue as analyzed in #58690, the underlying problem is that one of the new trimming optimizations is to remove parameter names of methods that were not visible targets of reflection and this is breaking System.Text.Json. Reflection-based System.Text.Json has a lot of other trimming related problems. The only configuration of System.Text.Json that is well-supported with trimming is the source generated one (@eiriktsarpalis do we document this somewhere?). Anything else might require extra work in terms of trimming annotations (the publishing process will generate warnings and such apps need to be thoroughly re-tested after trimming). The annotation required here is likely to make it visible that the constructors of
If the target framework is .NET 5, we wouldn't produce warnings because at that time trimming was in preview and the warnings were suppressed. |
ok, I found a nice workaround. instead of
Since I don't need generics here it's ok for me. For backward compatibility members are named Item1/2, but that's ok. In future I'll try not to be lazy and create class for use case like this. My app is back on linking. Interesting is, that excluding System.Text.Json from trimming was not enough. |
The problem is in removing parameter names on the constructor of the Tuple class and that one is in CoreLib. So you would need to disable trimming on CoreLib.
The workaround works because ExampleValueItem is now defined in your assembly and I assume your assembly is not manifested as trimmable and it's not trimmed as a result. (By default, pretty much only the framework is trimmed.) It would be the best to use the source generated Json. It will avoid problems like this (exception that is not possible to reason about or root cause easily). |
Yes, I would say it is fairly well-documented both in the API and conceptual doc level. See also https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation-modes
I would still recommend using the source generator in .NET 6 since the reflection-based serialization modes are not supported with trimming and could fail in unexpected ways. I think we can close this as by-design. We should still update the reflection-based serializer to better anticipate trimmed parameter names and fail with a helpful error message, which is tracked by #58690. |
@MichalStrehovsky thank you for your comprehensive answer! really appreciate it. I'll stay with my custom non generic class and will avoid serializing Tuples. |
One more note that reflection-based serializers are known to be incompatible with trimming and the recommendation is to use a source generated replacement, like the source-generated version of System.Text.Json that Eirik linked to. |
Description
Class:
fails to deserialize when published as self contained and trim mode link. (linux-arm, I haven't tried other platforms). When using trim mode CopyUsed - everything works, but my app is almost 50% bigger.
json example:
Reproduction Steps
small example compiled as self contained and
JsonSerializer.Deserialize<Example>(str);
Expected behavior
To deserialize json.
Actual behavior
Exception:
Regression?
Yes. It was working in NET5. After installing NET6 it doesn't work in NET5. Net6 linker is used to compile NET5 project?
Known Workarounds
Use TrimMode=CopyUsed
Configuration
-r linux-arm -p:PublishTrimmed=True -p:TrimMode=CopyUsed --self-contained true -c Release -f net6.0
Other information
No response
The text was updated successfully, but these errors were encountered: