-
-
Notifications
You must be signed in to change notification settings - Fork 80
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
Switch to System.Text.Json #100
Conversation
It doesn't look like some of the functionality that JSON.Net has exists in System.Text.Json, specifically the handling of default values. Currently JSON.Net is configured to ignore default values however you can't do that with System.Text.Json. Assuming I can get everything else to work, I think this still might be a deal breaker. |
A few more opinionated changes in the The short of it is:
|
Currently through getting the tests working, there is a big blocker with: dotnet/corefx#38841 I could manually change every |
This is good stuff. I wondered if there would be road blocks like null value handling problems. With regards to HTML escaping by default. There are times when you might not want to do that (you're not working in a web context), so we need to provide both methods. Regarding https://github.com/dotnet/corefx/issues/38841, it may be that we need to wait for .NET Core 3.1 before this PR can be accepted. Can you not set the order with System.Text.Json at all? I wouldn't mind a complete switch to the new attributes if required. We don't support any other serialization like XML, so there is no benefit to using |
As far as I've seen in the source code, no it doesn't seem possible to set the order with the new property. I have a feeling they probably won't have that functionality though as according to the JSON spec, an object is an unordered list of name/value pairs. As far as I can tell, the serializer will put inherited properties at the end so it is at least still predictable, just that all the tests that do a string comparison will need to have their properties moved around. I've updated the I'm happy to wait for 3.1 to see if |
Happy to move to The ordering is a bigger problem as you have to mess with all of the tests which is a bigger job and much harder to review the PR. If there are no plans to implement ordering in 3.1, then perhaps we should go ahead with it, otherwise wait for 3.1. Thoughts? |
I really don't see them bringing across ordering to It does suck needing to change the tests, less because of the work to do it, more because it is far nicer having the code meet the tests rather than updating both (code and tests) to meet each other. I'll look at getting this done soon, even if it is just so we can see if there are any other deal breakers with switching to |
Note for self: Need to update |
Instead of comparing exact string representations in our tests, perhaps we should compare JSON object types from System.Text.Json? |
That could work! So with Newtonsoft that was The only exception to this is still specifically checking how the |
Yes, I hadn't thought of that. I guess string comparisons are still important. The System.Text.Json API must still output a deterministic order for all it's properties, so I guess it might be best to bite the bullet and fix the tests to match. |
Another note to self: There looks to be a more efficient way to cast raw JSON to value types than using |
Had to move to a preview version of A few tests are now passing with no change (eg. |
Two curly issues I've needed to work around due to how Case in point, the Similarly when serializing a Ultimately though we are still stuck with default values being serialized. The "IgnoreNullValues" requires classes but because the property types are structs, that never works so the serialized JSON is full of |
I threw together a basic "Thing" converter which mitigates the need for |
I've fixed issue #104 for |
Do you think we're close with this or should I start to think about fixing it with JSON.NET? |
For the most part, yeah we are close. The biggest issue is still the lack of ignoring default values - I have a work around which basically takes over all serialization of all schema entities, just needs the Until we know the path for ignoring default values (whether to use my workaround or wait till real support), there isn't much point altering the tests. Doing so currently will still lead to test failures because of a lot of If you're happy with me using my workaround, I can continue but otherwise, it is a waiting game for dotnet/corefx#38878 to be done. |
Just throwing my 2cents in here: Really exciting to see this working, and great how much progress we’ve been able to make and contribute back to corefx issues at the same time to help steer System.Text.Json. I help maintain a library (OpenActive.NET) on top of Schema.NET - expecting this change - so great to see it’s progressing. My quick thought was given that Schema.NET is in use in production across a large number of systems, I’m not sure we need to push ourselves to be white-knuckle-bleeding-edge here? Perhaps sticking with the tried and tested JSON.NET while System.Text.Json settles into mainstream use would be best - especially now we’ve done the hard work to identify which bits of System.Text.Json we need to see improvements in before migrating? Although we gain performance in theory using System.Text.Json (though perhaps not so much with the workaround still in place?) it doesn’t seem like there’s any obvious functional benefit here and we’re increasing complexity by being an early adopter? As I say just my 2cents, is really great to be able to give the MS team feedback on where we’ve found issues with the new functionality, just not sure if we need to go the whole way just yet? |
Those are fair points you've raised @nickevansuk - I too am working on a pretty substantial project where Schema.NET plays a vital part so I definitely want to make sure it is stable, fast and memory efficient. I don't imagine the workaround for default values performing any slower than having that functionality built-in (both do caching of certain reflected property lookups) but it would increase the overall code maintenance required for the library. On the other hand, once working support for ignoring default values lands, it would make it redundant so it likely wouldn't be around long-term. Keeping with JSON.Net for now also does allow the library to keep .NET Standard 1.1 support (that was one of the first things that had to go for What might be good in the meantime is actually beefing up the tests (I found some while doing this PR that don't seem to be adequately testing what I think they should be), adding some basic benchmarking (both to optimise the current code and to measure the performance improvement when going to If @RehanSaeed is happy for those types of things, I'm happy to focus on those things and let this PR sit till |
If we still want to go ahead with |
Happy to wait for .NET 5 if it makes it easier. In that case we need to fix #104 but I don't have much time in the short term. Also as an aside if we want to add System.Text.Json, we should consider adding an option to serialize directly to UTF8 which is a bit faster. I've done this with some other code I've been working on but not given it much thought with Schema.NET. |
See docs about serializing to and from UTF8 https://docs.microsoft.com/en-gb/dotnet/standard/serialization/system-text-json-how-to |
b355ec2
to
ecb09a1
Compare
I've done a preliminary benchmark run on
I did have another thought regarding improving serialization/deserialization performance by having Schema.NET.Tool generate custom converters for each type. Technically we have all the pieces we need in the tool with each property and the ancestor properties etc plus we know all the types ahead of time. Unless I think this is something worth pursuing and could actually make the need for ignoring default values redundant. Also, we would have control of the property order so the tests could stay as they are. |
With dotnet/runtime#36322 - it looks like we will be closer to moving this forward and not needing to worry about default values. Will keep my eye out if there are any beta versions of the System.Text.Json library out with this new change so we can keep progressing on this. |
Actually makes the "allow trailing commas" change work
The values can be null here
a4dc45d
to
df836cb
Compare
Took a bit longer to get sorted than I thought but it seems to all be good! Any final things you want to check before we merge @RehanSaeed ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM minus a couple of very minor suggestions. Feel free to complete.
Yay, finally after a few years it was done. 😄 |
Attempts to resolve #96 , switching from JSON.Net to System.Text.Json.
One problem with the migration is it requires dropping .NET Standard 1.1 support. I've done that in this PR already however if you're wanting to maintain that, it might be possible with falling back to JSON.Net but likely will require a ton of
#if
declarations in every class.Current status: Down from 27000 errors to 0 - just testing is left.