首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >用Json.Net反序列化未知类型时发生意外错误

用Json.Net反序列化未知类型时发生意外错误
EN

Stack Overflow用户
提问于 2017-03-29 13:42:36
回答 1查看 994关注 0票数 1

在下面的代码中,我使用Json.Net序列化一个对象。这个Json嵌入了类型名。然后,我更改其中一个类型名称以导致错误(这是一个测试,我正在处理现有项目中的一个实际问题)。当我反序列化Json时,我希望得到一个对象,该对象对于带有篡改类型名称的属性具有一个空值。相反,序列化程序退出并返回null。我的期望正确吗?我是否可以以某种方式更改设置,以便为根对象获得一个非空对象?请注意,我得到的第二个错误表明序列化程序中存在一个错误。

代码语言:javascript
运行
AI代码解释
复制
static public class JsonTest
{
    static public void Test()
    {
        // Create test object
        A a = new A
        {
            MyTest = new MyTest(),
        };

        // Serialize it. 
        string json = JsonConvert.SerializeObject(a, new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto
        });

        // Fiddle class name to induce error
        json = json.Replace("+MyTest", "+MyTest2"); 

        // Before: {"MyTest":{"$type":"<Namespace>.JsonTest+MyTest, <Assembly>"}}
        // After: {"MyTest":{"$type":"<Namespace>.JsonTest+MyTest2, <Assembly>"}}

        // Deserialize
        A a2 = JsonConvert.DeserializeObject<A>(json, new JsonSerializerSettings
        {
            TypeNameHandling = TypeNameHandling.Auto,
            Error = (object sender, ErrorEventArgs e) =>
            {
                e.ErrorContext.Handled = true; // Should have only one error: the unrecognized Type
            }
        });

        // A second error occurs: Error = {Newtonsoft.Json.JsonSerializationException: Additional text found in JSON string after finishing deserializing object....
        // a2 is null
    }

    public class A
    {
        public ITest MyTest { get; set; }
    }

    public interface ITest { }
    public class MyTest : ITest { }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-29 20:20:46

更新

问题已在Json.NET 10.0.2 in 本意见书中修复。

原始答案

这看起来是Json.NET中的一个bug。如果我设置了JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead,那么问题就消失了:

代码语言:javascript
运行
AI代码解释
复制
// Deserialize
A a2 = JsonConvert.DeserializeObject<A>(json, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto,
    MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead,
    Error = (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e) =>
    {
        Debug.WriteLine(e.ErrorContext.Path);
        e.ErrorContext.Handled = true; // Should have only one error: the unrecognized Type
    }
});

Debug.Assert(a2 != null); // No assert. 

但是,不需要打开此设置,它允许读取元数据属性,包括位于JSON对象中任何位置的"$type",而不仅仅是作为第一个属性。最有可能的是,它巧合地修复了bug,因为它需要在开始反序列化之前预先加载整个JSON对象。

如果你想的话,你可以报告问题

稍微调试一下,问题似乎是,由于无法构造内部MyTest对象,JsonSerializerInternalReader.PopulateObject()在填充外部对象A时捕获和处理异常。正因为如此,JsonReader没有经过内部嵌套的对象,使读取器和序列化程序处于不一致的状态。这说明了第二个异常和最终的Additional text found in JSON string after finishing deserializing object. Path ''异常。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43104683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档