Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Newtonsoft.Json: error on deserialize objects with generic fields

I have a question: Does Json.NET correctly work with generics? I have the next code:

[TestClass]
public class TestClass1_Test
{
    [TestMethod]
    public void ToJson()
    {
        var mot = new TestClass1(1, "title");
        var result = mot.ToJson();
        Assert.IsNotNull(result);

        var pobject = TestClass1.FromJson(result);

        Assert.AreEqual(pobject.Id, mot.Id);
    }
}

public class TestClass1
{
    public TestClass1(int id, string name)
    {
        Id = new Field<int>(id);
        Name = new Field<string>(name);
    }

    public Field<int> Id { get; set; }
    public Field<string> Name { get; set; }

    public string ToJson()
    {
        var jobject = JObject.FromObject(this);
        return jobject.ToString();
    }

    public static TestClass1 FromJson(string json)
    {
        var obj = JObject.Parse(json).ToObject<TestClass1>();
        return obj;
    }
}

public class Field<T>
{
    public Field(T val)
    {
        Value = default(T);
    }
    public T Value { get; set; }
}

But when I call var obj = JObject.Parse(json).ToObject<TestClass1>() I get next error:

Newtonsoft.Json.JsonReaderException: Error reading integer. Unexpected token: StartObject. Path 'Id', line 2, position 10.

Where is my mistake? Or Json.NET does not work with generics?

like image 685
Sergey Shulik Avatar asked Apr 21 '26 21:04

Sergey Shulik


2 Answers

Json.NET does indeed work with generics - I was able to serialize and deserialize one of your Field<int> objects just fine.

The error message I get with the above code (using Json.NET 4.5 r10) is:

Error reading integer. Unexpected token: StartObject. Path 'Id', line 2, position 10

where the stack trace implied it was trying to deserialize an integer when it ran into a {, which was the beginning of the Id object. I think this could well be a bug.

Yet this seems to work as expected when using Json.NET 3.5 r8. I did have to swap JsonConvert.DeserializeObject<TestClass1>(json) for JObject.Parse(json).ToObject<TestClass1>() as the latter isn't in this version.

The answer therefore is to try a different version of Json.NET.

There is also a bug in the Field constructor.

Value = default(T);

should be:

Value = val;
like image 190
nick_w Avatar answered Apr 24 '26 10:04

nick_w


For reference; this error can also come about if you are deserializing an object that contains a nested JSON object as a string.

If you forget to stringify it, the parser throws up this error.

like image 33
79E09796 Avatar answered Apr 24 '26 09:04

79E09796



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!