反序列化json时的异常

Posted

技术标签:

【中文标题】反序列化json时的异常【英文标题】:Exception when deserializing json 【发布时间】:2016-10-08 04:10:35 【问题描述】:

我有两种方法

public static string SerializeObject<T>(T value)

    if (value == null)
    
        return null;
    

    var dictionaryObject = new Dictionary<string, object>   typeof(T).Name, value  ;

    var jsonString = JsonConvert.SerializeObject(dictionaryObject);

    return jsonString;

public static T DeserializeObject<T>(string jsonString)

    var objectValue = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
    return JsonConvert.DeserializeObject<T>(objectValue.Values.First().ToString());

当我反序列化一个带有类型的 json 字符串时

ConcurrentDictionary<KeyValuePair<long, long>, IList<string>>

我有一个例外:

无法将字符串“[1, 1]”转换为字典键类型“System.Collections.Generic.KeyValuePair`2[System.Int64,System.Int64]”。创建一个 TypeConverter 以从字符串转换为键类型对象。路径“[1, 1]”,第 2 行,位置 12。

那么有人可以告诉我正确的代码吗?

这是我的代码:

var test = new ConcurrentDictionary<KeyValuePair<long, long>, IList<string>>();
test.TryAdd(new KeyValuePair<long, long>(1, 1), new List<string>  "Test" );

var se = SerializeObject(test);

var de = DeserializeObject<ConcurrentDictionary<KeyValuePair<long, long>, IList<string>>>(se);

【问题讨论】:

你为什么要把它变成字典? 您可能需要多解释一下您要完成的工作。不确定您要使用 Dictionary 解决什么问题。 @ user1334007:我正在尝试将 json 字符串反序列化为 ConcurrentDictionary, IList> 类型的对象 只删除字典的东西,没有意义。另外你有一些相当奇怪的数据结构,也许可以尝试使用一个类作为 DTO(数据传输对象),它会简化你的代码并使其更符合逻辑 【参考方案1】:

我不确定这是否是最好的解决方案,但是,请试试这个:

1) 按照this topic 中的说明创建ContractResolver。

class DictionaryAsArrayResolver : DefaultContractResolver
        
            protected override JsonContract CreateContract(Type objectType)
            
                if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) ||
                    (i.IsGenericType &&
                     i.GetGenericTypeDefinition() == typeof(IDictionary<,>))))
                
                    return base.CreateArrayContract(objectType);
                

                return base.CreateContract(objectType);
            
        

2) 稍微更改一下您的序列化/反序列化方法:

public static string SerializeObject<T>(T value, JsonSerializerSettings settings)
        
            if (value == null)
            
                return null;
            

            var dictionaryObject = new Dictionary<string, object>   typeof(T).Name, value  ;
            var jsonString = JsonConvert.SerializeObject(dictionaryObject, settings);

            return jsonString;
        

        public static T DeserializeObject<T>(string jsonString, JsonSerializerSettings settings)
        
            var objectValue = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString, settings);
            return JsonConvert.DeserializeObject<T>(objectValue.Values.First().ToString(), settings);
        

3) 检查测试:

[TestMethod]
        public void Test()
        
            var test = new ConcurrentDictionary<KeyValuePair<long, long>, IList<string>>();
            test.TryAdd(new KeyValuePair<long, long>(1, 1), new List<string>  "Test" );

            JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.ContractResolver = new DictionaryAsArrayResolver();

            var se = SerializeObject(test, settings);

            var de = DeserializeObject<ConcurrentDictionary<KeyValuePair<long, long>, IList<string>>>(se, settings);
        

希望对你有帮助 =)

【讨论】:

成功了,感谢您的解决方案 :) @Johnny Svarog

以上是关于反序列化json时的异常的主要内容,如果未能解决你的问题,请参考以下文章

使用Java中的Jackson反序列化异常/抛出时的问题

在 FromForm 中反序列化 JSON 时的生命周期

反序列化时的映射问题

反序列化json的坑

json大数据量序列化与反序列化慢

Retrofit 在 JSON 反序列化的时候提示 UnrecognizedPropertyException 异常