1

I saw other similar questions/answers but none show both serialization/deserialization

Example:

public class DeepNested {
    [JsonProperty]
    int X { get; }

    [JsonProperty]
    int Y { get; }

    public DeepNested(int x, int y) { X = x; Y = y; }

    [JsonConstructor]
    public DeepNested(DeepNested dn) { X = dn.X; Y = dn.Y; }
}

public class Nested {
    [JsonProperty]
    DeepNested DN { get; }

    [JsonProperty]
    int Z { get; }

    [JsonProperty]
    int K { get; }

    [JsonConstructor]
    public Nested(DeepNested dn, int z, int k) { DN = new DeepNested(dn); Z = z; K = k; }
}

public class C {
    [JsonProperty]
    Nested N { get; }

    [JsonConstructor]
    public C(Nested n) { N = n; }
}

class Program {
    static void Main(string[] args) {
        var deepNested = new DeepNested(1,2);
        var nested = new Nested(deepNested, 3, 4);
        C c = new C(nested);
        string json = JsonConvert.SerializeObject(c);
        C c2 = JsonConvert.DeserializeObject<C>(json);
        Console.WriteLine(json);
    }
}

I get an exception on DeepNested.DeepNested(DeepNested dn)

System.NullReferenceException: 'Object reference not set to an instance of an object.'

The debugger shows dn is null

This seems be a serious limitation of Json.NET unless I'm missing something ?

6
  • Can you please post the JSON you are trying to deserialize Commented Jul 6, 2018 at 3:51
  • I'm trying for example to serialize a C object to json and then deserialize it back Commented Jul 6, 2018 at 3:57
  • Have you tried creating parameterless constructor and making the properties have getter and setter both Commented Jul 6, 2018 at 3:59
  • well that would not be very immutable .. Commented Jul 6, 2018 at 4:13
  • 1
    class DeepNested -> move [JsonConstructor] to public DeepNested(int x, int y) constructor Commented Jul 6, 2018 at 5:39

2 Answers 2

3

@IpsitGaur is right, commonly you should have a default public constructor and publicly accessable properties (mutable). But JSON.Net is a very powerfull tool!

If you need to handle non-default constructor, you may use JsonConstructorAttribute. For your code, example may be like this:

public class Nested
{
    public int X { get; }
    public int Y { get; }

    [JsonConstructor]
    Nested(int x, int y) { X=x; Y=y; }
}

public class C
{
    public Nested N { get; }

    [JsonConstructor]
    public C(Nested n) { N = n; }
}

var c1 = new C(new Nested(1, 2));
var json = JsonConvert.SerializeObject(c1); // produce something like "{\"n\":{\"x\":1,\"y\":2}}";
var c2 = JsonConvert.DeserializeObject<C>(json);
Sign up to request clarification or add additional context in comments.

4 Comments

I'd recommend including an example in your answer rather than relying on an off-site resource which could be subject to link rot.
@john Ok, I will add an example, but also I will leave this link to official JSON.Net documentation (for further reading).
thanks ! I edited my question to show how a second level of nesting breaks this, pls have a look
@kofifus, I add both (serialization/deserialization)
0

The following works...

public class Nested
{
    [JsonProperty]
    int X { get; }

    [JsonProperty]
    int Y { get; }

    public Nested(int x, int y) { X = x; Y = y; }
}

public class C
{
    [JsonProperty]
    Nested N { get; }

    public C(Nested n) { N = n; }
}

class Program
{
    static void Main(string[] args)
    {
        Nested nested = new Nested(1, 2);
        C c = new C(nested);
        string json = JsonConvert.SerializeObject(c);
        C c2 = JsonConvert.DeserializeObject<C>(json);
    }
}

1 Comment

thanks ! I edited my question to show how a second level of nesting breaks this, pls have a look

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.