Sergey Shulik
Sergey Shulik

Reputation: 1010

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?

Upvotes: 3

Views: 6253

Answers (2)

79E09796
79E09796

Reputation: 2230

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.

Upvotes: 1

nick_w
nick_w

Reputation: 14938

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;

Upvotes: 2

Related Questions