Newtonsoft.Json:反序列化带有泛型字段的对象时出错

3
我有一个问题:Json.NET是否正确地处理泛型?我有下面的代码:
[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; }
}

但是,当我调用var obj = JObject.Parse(json).ToObject<TestClass1>()时,我遇到了以下错误:

Newtonsoft.Json.JsonReaderException:读取整数时出错。意外的令牌:StartObject。路径 'Id',行 2,位置 10。

我的错误在哪里? 或者Json.NET不支持泛型?


出于好奇,为什么你不直接在类上设置类型 public int Id { get; set;}?Field<T> 有什么用途?我猜想这是因为 Field<Int> != Int,即 Newtonsoft 不知道 Field<Int> 是什么。也许你可以为 Field<T> 编写自定义转换器? - Mike
@Mike,这只是一个例子。我想要了解Json.NET如何与泛型一起使用。在现实生活中,领域更加复杂。 - Sergey Shulik
2个回答

2

Json.NET确实可以使用泛型 - 我能够成功地序列化和反序列化你的Field<int>对象。

使用上述代码时,我收到了以下错误消息(使用Json.NET 4.5 r10):

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

堆栈跟踪表明它在尝试反序列化整数时遇到了一个 {,这是 Id 对象的开始。我认为这可能是一个错误。

然而,在使用 Json.NET 3.5 r8 时,这似乎按预期工作。我不得不将 JsonConvert.DeserializeObject<TestClass1>(json) 替换为 JObject.Parse(json).ToObject<TestClass1>(),因为后者在此版本中不存在。

因此,答案是尝试使用不同版本的 Json.NET。

Field 构造函数中也存在一个错误。

Value = default(T);

should be:

Value = val;

1
参考资料:如果您正在将包含嵌套JSON对象的对象反序列化为字符串,则此错误也可能出现。
如果您忘记对其进行字符串化,解析器将抛出此错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接