-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Undocumented breaking change in .NET 5.0 - HashSet moved to another assembly/library #47113
Comments
Tagging subscribers to this area: @eiriktsarpalis Issue DetailsHello everyone, public class TestClass
{
public IReadOnlyDictionary<string, IReadOnlyCollection<string>> Dictionary { get; }
public TestClass(IReadOnlyDictionary<string, IReadOnlyCollection<string>> dictionary)
{
Dictionary = dictionary;
}
} resulting in (with a collection in a dictionary's value being {
"Dictionary": {
"DictionaryKey": {
"$type": "System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib]], System.Collections",
"$values": [
"string value"
]
}
}
} whereas in {
"Dictionary": {
"DictionaryKey": {
"$type": "System.Collections.Generic.HashSet`1[[System.String, System.Private.CoreLib]], System.Private.CoreLib",
"$values": [
"string value"
]
}
}
} The The problem of couse occurs when trying to deserialize old-netcoreapp3.1 events/messages into the application running on My questions are basically:
|
Moving types among assemblies isn't treated as breaking change for common cases. There's
There are, but not frequently. Types will be moved when the implementation structure requires so.
Such serialization can be more incompatible with .NET Framework, since many types have moved and the corelib name has changed. |
If it isn't, I think it should be treated as such.
And of course assembly name for the given type is the public API. And my question (let me quote myself) was regarding any other such a breaking changes for .NET 5.0 release:
|
In public API, it stays remaining in the original assmebly. Serialization using reflection is getting implementation detail. For example, there is no Implementation detail can be broken in any release. |
The type has moved many times already. Serializers should ideally respect the runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs Line 16 in 0df028b
Libraries have type forwarders (using the above mentioned |
Then a question to @JamesNK : does the |
That question should be asked over at the Newtonsoft.Json repo (https://github.com/JamesNK/Newtonsoft.Json). This repo is specifically for .NET. (Also, standard disclaimer: TypeNameHandling.Auto should be used with extreme caution. It's a code execution equivalent. Your service's threat model should consider whether the entity supplying the JSON contents to deserialize is trustworthy.) |
Issue about this here - JamesNK/Newtonsoft.Json#1972 This was suggested as a solution - JamesNK/Newtonsoft.Json#1972 (comment) |
Resolving as by design - we move types with Type Forwarding often. The attribute was specifically created so this could be done transparently (if it is respected) |
@danmoseley can you comment on this issue JamesNK/Newtonsoft.Json#1972 ? ie should the fix be included in jsondotnet or in the runtime? |
Perhaps @steveharter can help there. |
@dandanmu @steveharter note the "suggested solution" points to my workaround here, which i would consider a temporary hack, which is also in no way discoverable when the problem occurs |
@danmoseley @steveharter can i provide any more information or help on this one? |
@danmoseley @steveharter can this be re-opened. since it seems comments on closed issues are often lost in the ether |
In theory we could add a reflection API |
Adding APIs to improve binary serialization would violate the principles we have set in https://github.com/dotnet/designs/blob/main/accepted/2020/better-obsoletion/binaryformatter-obsoletion.md.
This hack is appropriate to workaround buggy implementation of binary serialization contract in Newtonsoft.Json. The proper fix is to migrate away from using binary serialization. |
@jkotas this is happening in non-binary serialization |
"Binary serialization" is the wrong technical term, but it includes the umbrella of "serializers which embed type information in the payload," so the general concept is applicable here. That's also what I was trying (poorly) to say earlier w.r.t. Microsoft not investing in this category of serialization tech any further. |
so what is the plan here? the current status is far from ideal, ie a type load exception with no pointer to the how to resolve it. Expecting people to find a workaround 15 comments down on an issue is, IMO, not the "pitt of success". and the suggestion in binaryformatter-obsoletion.md of "move to System.Text.Json" is a poor answer with System.Text.Json being far from feature parity with json.net, again assuming they even follow the thread far enough to find binaryformatter-obsoletion.md. |
you might want to update the title of that binaryformatter-obsoletion.md. since i suspect many would read the title and immediately assume "i am not using binaryformatter, so this in no way applies to me" |
You requested this issue be reactivated - I assumed you wanted to propose something? From the .NET libraries team's perspective, there's nothing for us to do since the issue appears to exist solely within the third-party library Newtonsoft.Json. What I had suggested earlier is that if it would benefit the ecosystem, we could make |
I'm going to close this issue since there don't seem to be any actionable proposals from the libraries perspective. Feel free to reopen if this changes. |
Hello everyone,
I've stumbled upon a breaking change which as far as I've searched for was not documented anywhere.
It seems that with that pull request #37180
HashSet
was moved fromSystem.Collections
toSystem.Private.CoreLib
library.Let's say we have a fair big distributed system based on microservices with an immutable events used for a synchronization between them which are being stored forever.
Newtonsoft.Json
is being used as a serializer/deserializer.The problem with that breaking change is like in the example below:
that's an example of class which was serialized in a
netcoreapp3.1
version (with a collection in a dictionary's value beingHashSet
):resulting in (with a collection in a dictionary's value being
HashSet
)whereas in
net5.0
it is being serialized asThe
TypeNameHandling
is set toAuto
.The problem of couse occurs when trying to deserialize old-netcoreapp3.1 events/messages into the application running on
net5.0
My questions are basically:
$type
would be ignored for those types?The text was updated successfully, but these errors were encountered: