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

NullRefereceException when using a JsonConverter without a parameterless constructor #399

Closed
hillin opened this issue Nov 27, 2019 · 11 comments

Comments

@hillin
Copy link

hillin commented Nov 27, 2019

https://github.com/dotnet/corefx/blob/dfe3ab2f0205436e23b93c369ee0b2e41a4973e0/src/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs#L208-L209

ctor will be null if type does not have a parameterless constructor.

@layomia layomia transferred this issue from dotnet/corefx Nov 29, 2019
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Nov 29, 2019
@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Nov 29, 2019
@layomia layomia added this to the 5.0 milestone Nov 29, 2019
@piotrsz1234
Copy link

I thought, does this could be fixed, by using another constructor, to which would be given, parameters, which all, are null?
If that solution is good, I would like to work on that issue.

@hillin
Copy link
Author

hillin commented Dec 2, 2019

@piotrsz1234 It's perfectly fine that the JsonConverterAttribute expects a converter type which has a public parameterless constructor, and throws an exception otherwise. It's just the exception should be a well-defined one (like the ThrowHelper.ThrowInvalidOperationException_SerializationConverterOnAttributeInvalid below), rather than a simple NullReferenceException which is more difficult to track down. So I guess a null check would do the trick.

@piotrsz1234
Copy link

@hillin Right.
I guess everyone remembers to put empty constructor for class which is serializable.

@ahsonkhan
Copy link
Member

Here's a repro of the issue. The null ref only occurs when the converter is used within the JsonConverterAttribute.

[Fact]
public static void ConverterWithoutDefaultCtor()
{
    string json = @"{""MyType"":""ABC""}";
    Foo obj = JsonSerializer.Deserialize<Foo>(json);
    Assert.Null(obj.MyType);
}

[JsonConverter(typeof(MyConverter))]
public class Foo
{
    public string MyType { get; set; }
}

internal class MyConverter : JsonConverter<Foo>
{
    public MyConverter(int x)
    {

    }

    public override Foo Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }

    public override void Write(Utf8JsonWriter writer, Foo value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}
System.Text.Json.Serialization.Tests.ReadValueTests.ConverterWithoutDefaultCtor [FAIL]
      System.NullReferenceException : Object reference not set to an instance of an object.
      Stack Trace:
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializerOptions.Converters.cs(209,0): at System.Text.Json.JsonSerializerOptions.GetConverterFromAttribute(JsonConverterAttribute converterAttribute, Type typeToConvert, Type classTypeAttributeIsOn, PropertyInfo propertyInfo)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializerOptions.Converters.cs(130,0): at System.Text.Json.JsonSerializerOptions.GetConverter(Type typeToConvert)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializerOptions.Converters.cs(86,0): at System.Text.Json.JsonSerializerOptions.DetermineConverterForProperty(Type parentClassType, Type runtimePropertyType, PropertyInfo propertyInfo)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonClassInfo.cs(560,0): at System.Text.Json.JsonClassInfo.GetClassType(Type type, Type parentClassType, PropertyInfo propertyInfo, Type& runtimeType, Type& elementType, Type& nullableUnderlyingType, MethodInfo& addMethod, JsonConverter& converter, Boolean checkForAddMethod, JsonSerializerOptions options)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonClassInfo.cs(121,0): at System.Text.Json.JsonClassInfo..ctor(Type type, JsonSerializerOptions options)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializerOptions.cs(324,0): at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type classType)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\ReadStackFrame.cs(147,0): at System.Text.Json.ReadStackFrame.Initialize(Type type, JsonSerializerOptions options)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.Helpers.cs(15,0): at System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, Utf8JsonReader& reader)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.String.cs(89,0): at System.Text.Json.JsonSerializer.Deserialize(String json, Type returnType, JsonSerializerOptions options)
        E:\GitHub\Fork\corefx\src\System.Text.Json\src\System\Text\Json\Serialization\JsonSerializer.Read.String.cs(31,0): at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
        E:\GitHub\Fork\corefx\src\System.Text.Json\tests\Serialization\ReadValueTests.cs(75,0): at System.Text.Json.Serialization.Tests.ReadValueTests.ConverterWithoutDefaultCtor()

Ideally, such issues will get fixed by annotating nulls: #114 (comment)

@ahsonkhan ahsonkhan added the help wanted [up-for-grabs] Good issue for external contributors label Dec 7, 2019
@MarcoRossignoli
Copy link
Member

@piotrsz1234 are you working on this?

@piotrsz1234
Copy link

@MarcoRossignoli No

@piotrsz1234
Copy link

But it isn't hard fix. I guess some work with finding class using Assembly.

@MarcoRossignoli
Copy link
Member

I think that the fix is simply throw a clear exception right @ahsonkhan?

@ahsonkhan
Copy link
Member

@ahsonkhan ahsonkhan removed the help wanted [up-for-grabs] Good issue for external contributors label Dec 9, 2019
@MarcoRossignoli
Copy link
Member

I see

@layomia
Copy link
Contributor

layomia commented Feb 1, 2020

Fixed in #528.

@layomia layomia closed this as completed Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants