JSON .Net Unity反序列化匿名对象字典 [英] JSON .Net Unity Deserialize dictionary of anonymous objects

查看:130
本文介绍了JSON .Net Unity反序列化匿名对象字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字典,我将其序列化为一个二进制文件,然后使用JSON .net从 https://进行反序列化. json.codeplex.com/

I have a Dictionary that I serialize onto a binary file, and deserialize back again using JSON .net from https://json.codeplex.com/

字典可能包含缩写对象(字符串,类,甚至是List).每个类都是[System.Serializable]

The dictionary may contain abritrary objects (string, classes, even List). Each class is [System.Serializable]

在序列化时,我添加了serializer.TypeNameHandling = TypeNameHandling.All;确保反序列化器具有反序列化字典所需的类型信息.

At serialize time, I add serializer.TypeNameHandling = TypeNameHandling.All; to make sure the deserializer has the type info required to deserialize the dictionary.

我无法正确地将其反序列化为相同的对象列表,我仅在我的容器中获得JObjects,而不是原始类型.谁能帮我完成这个任务?

I am unable to deserialize it correctly to the identical list of object, I only get JObjects in my container and not the original type. Can anyone help me accomplish this?

预先感谢; 洛朗(Laurent)

Thanks in advance; Laurent

更新:

要获取数据,我使用这两种方法:

To get data in / out I use those two methods:

public static byte[] SerializeToByteArray<T>(T data)
{
    byte[] serializedData = new byte[]{}; 

    using(var stream  = new MemoryStream())
    {
        using (BsonWriter writer = new BsonWriter(stream))
        {
            JsonSerializer serializer = new JsonSerializer();
            serializer.TypeNameHandling = TypeNameHandling.All;
            serializer.Serialize(writer, data);
        }

        return stream.ToArray();
    }
}

public static T DeserializeFromByteArray<T>(byte[] serializedData )
{
    using (var stream = new MemoryStream(serializedData))
    {
        using (BsonReader reader = new BsonReader(stream))
        {
            JsonSerializer serializer = new JsonSerializer();
            return (T)serializer.Deserialize<T>( reader );
        }
    }
}

[System.Serializable]
public class FavoriteLevel
{
public FavoriteLevel(string ID, int TYPE) { id = ID; type = TYPE;}
public string id;
public int type;
}

Dictionary<string,object> dict = new Dictionary<string,object>(1);
List<FavoriteLevel> levels = new List<FavoriteLevel>(1);
levels.Add (new FavoriteLevel("123",FavoriteType.Favorite) );
dict.Add ( "123", levels );        
byte[] data = SerializeToByteArray( dict );

Dictionary<string,object> incomingDict =     DeserializeFromByteArray<Dictionary<string,object>>( data );

object listBack = incomingDict["123"];
// ERROR: listBack is a Json object and not a List<FavoriteLevel> object

推荐答案

反序列化和序列化时需要设置serializer.TypeNameHandling = TypeNameHandling.All.否则,"$type"属性将被忽略.

You need to set serializer.TypeNameHandling = TypeNameHandling.All when deserializing as well as serializing. Otherwise, the "$type" property will be ignored.

因此:

public static class JsonExtensions
{
    public static byte[] SerializeToByteArray<T>(T data, JsonSerializerSettings settings)
    {
        using (var stream = new MemoryStream())
        {
            using (var writer = new BsonWriter(stream))
            {
                JsonSerializer serializer = JsonSerializer.Create(settings);
                serializer.Serialize(writer, data);
            }
            return stream.ToArray();
        }
    }

    public static T DeserializeFromByteArray<T>(byte[] serializedData, JsonSerializerSettings settings)
    {
        using (var stream = new MemoryStream(serializedData))
        {
            using (var reader = new BsonReader(stream))
            {
                JsonSerializer serializer = JsonSerializer.Create(settings);
                return (T)serializer.Deserialize<T>(reader);
            }
        }
    }
}

public static class TestClass
{
    public static void Test()
    {
        Dictionary<string, object> dict = new Dictionary<string, object>(1);
        List<FavoriteLevel> levels = new List<FavoriteLevel>(1);
        levels.Add(new FavoriteLevel("123", 0));
        dict.Add("123", levels);

        var settings = new JsonSerializerSettings();
        settings.TypeNameHandling = TypeNameHandling.All;

        byte[] data = JsonExtensions.SerializeToByteArray(dict, settings);

        Dictionary<string, object> incomingDict = JsonExtensions.DeserializeFromByteArray<Dictionary<string, object>>(data, settings);

        object listBack = incomingDict["123"];

        Debug.Assert(listBack.GetType() == levels.GetType()); // No assert.
    }
}

这篇关于JSON .Net Unity反序列化匿名对象字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆