Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Fix 3.0->3.1 regression in JSON serializing nested concurrent dictionaries #42772

Merged
merged 3 commits into from
Jan 14, 2020

Conversation

layomia
Copy link
Contributor

@layomia layomia commented Dec 12, 2019

Description

Fixes dotnet/runtime#670, where there was a regression between 3.0 and 3.1 where serializing nested concurrent dictionaries went from supported to unsupported. The issue also exists in master/5.0. dotnet/runtime#784 fixes it in master, and this PR ports the fix to 3.0.

In addition to the fix described above, this PR also also has a deserialization fix for an InvalidCastException thrown when a dictionary element type has a converter that returns a type different from the declared type, e.g. when you're deserializing Dictionary<string, MyClass>, where

private interface IClass { }

private class MyClass : IClass { }

private class MyFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        return typeToConvert == typeof(IClass) || typeToConvert == typeof(MyClass);
    }

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        return new MyStuffConverter();
    }
}

private class MyStuffConverter : JsonConverter<IClass>
{
    public override IClass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return new MyClass();
    }

    public override void Write(Utf8JsonWriter writer, IClass value, JsonSerializerOptions options)
    {
        writer.WriteNumberValue(1);
    }
}

In this case, the read method of the converter for typeof(MyClass) returns a type IClass (not the declared type, MyClass) which causes an InvalidCastException later in the deserialization flow.

Customer Impact

The ability to serialize nested concurrent dictionaries is restored: dotnet/runtime#670.

The deserialization scenario is an edge case, but the fix defends against leaking exceptions were it to occur.

Regression

No. The serialization change's tests are wide-ranging and covers various permutations of nested dictionaries, so a regression is unlikely.

The deserialization change adds more support without rescinding support. A regression is unlikely.

Risk

Low, per the regression section above.

@layomia layomia added this to the 3.1.x milestone Dec 12, 2019
@layomia layomia self-assigned this Dec 12, 2019
@danmoseley
Copy link
Member

Can you link to the change you’re back porting

@layomia
Copy link
Contributor Author

layomia commented Dec 13, 2019

dotnet/runtime#784 fixes dotnet/runtime#670 for runtime/master (5.0), but doesn't contain the change on deserialization described above. We can consider this PR a back-port + the deserialization change.

@ericstj ericstj added the Servicing-consider Issue for next servicing release review label Dec 16, 2019
Copy link
Member

@ericstj ericstj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM: @ahsonkhan or @steveharter can you also review?

Note that this cannot merge until it is approved for servicing. Please add the servicing template to the pull request description.

@ericstj ericstj added * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) and removed Servicing-consider Issue for next servicing release review labels Dec 17, 2019
@danmoseley
Copy link
Member

@ericstj is this ready for tactics consideration now? just noticed it's not tagged but I see the template above

@ericstj
Copy link
Member

ericstj commented Jan 7, 2020

Yeah this is good, @steveharter signed off on same code change in master.

@ericstj ericstj added Servicing-consider Issue for next servicing release review and removed * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) labels Jan 7, 2020
@danmoseley danmoseley changed the title Improve (de)serialization support for nested dictionaries Fix 3.0->3.1 regression in JSON serializing nested concurrent dictionaries Jan 7, 2020
@jamshedd jamshedd added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Jan 9, 2020
@jamshedd
Copy link
Member

jamshedd commented Jan 9, 2020

Approved for March.

@danmoseley danmoseley modified the milestones: 3.1.x, 3.1.3, 3.1.2 Jan 9, 2020
@danmoseley
Copy link
Member

Moved back to 3.1.2 per tactics.

@Anipik Anipik merged commit b855121 into dotnet:release/3.1 Jan 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants