Skip to content
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

Upgrade to .NET Core 3.1 broke serialization of System.Version. #2243

Closed
niemyjski opened this issue Dec 20, 2019 · 4 comments
Closed

Upgrade to .NET Core 3.1 broke serialization of System.Version. #2243

niemyjski opened this issue Dec 20, 2019 · 4 comments

Comments

@niemyjski
Copy link

niemyjski commented Dec 20, 2019

We are in the process of upgrading from .NET Core 2.2 to 3.1 and I noticed that we were getting serialization failures during testing. Looking into it, it was blowing up from trying to deserialize data coming from Elasticsearch that contained System.Version. I'm trying to track this down and will provide more information as I find it. I just wanted to get the ball rolling.

I also realize that there is a ton of test coverage already on System.Version. I just find it crazy (and thinking to myself that I'm going crazy) that we have no defined converters (like the VersionConverter in registered in our converter list) and we are using JSON.NET 12.0.(2|3) and the only change was the runtime which updated the BCL types. I totally get that creating a new type below can and would bypass any specific type checks inside of JSON.NET. But I'd expect to work the same across runtimes.

Source/destination types

        public class TestModel {
            public System.Version Version { get; set; }
            public System.Version2 Version2 { get; set; }
        }

serialized JSON

{"Version":"1.0","Version2":{"Major":1,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1}}

Expected behavior

I'd expect it to output the previous json for sake of backwards compatibility or provide a converter so we get a normalized output. I only found this because Elasticsearch was blowing up trying to deserialize these models after we upgraded to .net core 3.1 from 2.2

Link to current source for .NET Core 3.x System.Version
https://github.com/dotnet/corefx/blame/master/src/Common/src/CoreLib/System/Version.cs
Link to previous 2.2 System.Version:
https://github.com/dotnet/corefx/blob/b3efd32a0c529240ce520839e28031d8beb84b85/src/Common/src/CoreLib/System/Version.cs

I looked at the source and compared the two, it's basically all just basic newer language feature changes like null reference types, expression bodies.

Versions were previously outputted as

{"Major":1,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1}

Current:

"1.0"

Actual behavior

{"Version":"1.0","Version2":{"Major":1,"Minor":0,"Build":-1,"Revision":-1,"MajorRevision":-1,"MinorRevision":-1}}

Steps to reproduce

You can use the model above or you can run this with just the version field in a 2.2 console app and then change it to 3.1 should do the trick as well.

For Version2 type just copy the latest 2.2 corefx version of System.Version located here or get it from my gist here with minimal edits so it compiles.

            var model = new TestModel {
                Version = new Version(1, 0),
                Version2 = new Version2(1, 0)
            };

            string json = JsonConvert.SerializeObject(model, new JsonSerializerSettings());
@JamesNK
Copy link
Owner

JamesNK commented Dec 22, 2019

.NET Core 3 has a TypeConverter for Version: VersionConverter. Newtonsoft.Json automatically picks it up from TypeDescriptor.GetConverter(typeof(Version)).

You could write a JsonConverter to explicitly control how Version is serialized.

@JamesNK JamesNK closed this as completed Dec 22, 2019
@niemyjski
Copy link
Author

niemyjski commented Dec 23, 2019

Thanks for the reply. That was my first thought but then I didn't see a type converter on the Version class itself. Pretty sweet how there is not a type converter class directly on Version / any reference/documentation stating how it will be affected. I didn't even see a change log that states this behavior that I've seen and this is up there on breaking changes (changing how serialization happens to a type). I even searched GitHub but didn't see anything. Took digging through the issues and not the C# find results on GitHub (of which there was none) to find it.

Thanks again!

reference:
https://github.com/dotnet/corefx/pull/28516/files

@BasieP
Copy link

BasieP commented Mar 25, 2020

Same problem here. Hate that this is practically unfindable. Nothing in the changelogs.

How could this not work:

var json = JsonConvert.SerializeObject(new Version(1, 2, 3, 4));
var x = JsonConvert.DeserializeObject<Version>(json, new VersionConverter());  //CRASH

Very simple example of code screwup guys... please fix it

@ansariabr
Copy link

Thanks for the reply. That was my first thought but then I didn't see a type converter on the Version class itself. Pretty sweet how there is not a type converter class directly on Version / any reference/documentation stating how it will be affected. I didn't even see a change log that states this behavior that I've seen and this is up there on breaking changes (changing how serialization happens to a type). I even searched GitHub but didn't see anything. Took digging through the issues and not the C# find results on GitHub (of which there was none) to find it.

Thanks again!

reference:
https://github.com/dotnet/corefx/pull/28516/files

I also faced lot of issues due to this breaking change. I am surprised as to why this is no where mentioned in the change logs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants