unity-game-engine - unity Json.net bson 自引用循环

标签 unity-game-engine json.net bson

我正在尝试使用 Json.net 保存游戏中的内容。与 this我将游戏保存为 JSON,但现在我想将其保存为 Bson 格式,因为我不希望我的玩家能够轻松编辑保存文件。

这是代码的工作原理,并将我的游戏数据保存到 json。

File.WriteAllText(path, JsonConvert.SerializeObject(objectToSave, Formatting.Indented,
    new JsonSerializerSettings
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    }));

在这里,我尝试将游戏数据保存为 bson 格式,但我不太知道如何关闭 bson 格式的 ReferenceLoopHandling。

using (var stream = new MemoryStream())
{
    var serializer = new JsonSerializer();
    var writer = new BsonWriter(stream);
    serializer.ReferenceLoopHandling.Equals(false);
    serializer.Serialize(writer, objectToSave);

    File.WriteAllText(path, serializer.ToString());
}

当我运行此代码时,出现以下错误。

JsonSerializationException:检测到类型为“StoryGraph”的属性“graph”的自引用循环。路径“节点[0]”。

最佳答案

您可以使用工厂方法JsonSerializer.CreateDefault(JsonSerializerSettings)JsonSerializer.Create(JsonSerializerSettings)使用您所需的设置创建序列化器,然后使用以下扩展方法直接序列化到文件:

public static partial class BsonExtensions
{
    // In Json.NET 10.0.1 and later use https://www.nuget.org/packages/Newtonsoft.Json.Bson
    public static void SerializeToFile<T>(T obj, string path, JsonSerializerSettings settings = null)
    {
        using (var stream = new FileStream(path, FileMode.Create))
        using (var writer = new BsonWriter(stream)) // BsonDataWriter in Json.NET 10.0.1 and later
        {
            JsonSerializer.CreateDefault(settings).Serialize(writer, obj);
        }
    }

    public static T DeserializeFromFile<T>(string path, JsonSerializerSettings settings = null)
    {
        using (var stream = new FileStream(path, FileMode.Open))
        using (var reader = new BsonReader(stream)) // BsonDataReader in Json.NET 10.0.1 and later
        {
            var serializer = JsonSerializer.CreateDefault(settings);
            //https://www.newtonsoft.com/json/help/html/DeserializeFromBsonCollection.htm
            if (serializer.ContractResolver.ResolveContract(typeof(T)) is JsonArrayContract)
                reader.ReadRootValueAsArray = true;
            return serializer.Deserialize<T>(reader);
        }
    }
}

然后序列化如下:

BsonExtensions.SerializeToFile(objectToSave, path, 
                               new JsonSerializerSettings 
                               { 
                                   ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
                               });

注释:

  • 反序列化时请务必使用相同的设置。

  • BSON 支持已移至其自己的包中 Newtonsoft.Json.Bson在 Json.NET 10.0.1 。在此版本或更高版本中,您应该使用 BsonDataWriter (和 BsonDataReader )为 BsonWriter已过时,最终将被删除。

  • serializer.ToString() 不会返回序列化的 BSON;而是使用 MemoryStream.ToArray() ,即

    File.WriteAllBytes(path, stream.ToArray());
    

    但是,如上面的扩展方法所示,直接流式传输到文件会更有效。

  • serializer.ReferenceLoopHandling.Equals(false); 不是设置 ReferenceLoopHandling 的正确方法C# 中的属性。相反,将其设置为一个字段:

     serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    

    参见:Using Properties (C# Programming Guide) .

演示 fiddle here .

关于unity-game-engine - unity Json.net bson 自引用循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58635698/

相关文章:

mongodb - 为什么 mgo 不能正确解码我的结构?

android - 如何检查 Android Unity3d 的互联网连接类型

ios - 如何使用unity SDK保持登录Facebook

c# - 如何获取当前光标作为Texture2D Unity C#

macos - VS Code 找不到 OmniSharp 的 Mono

c# - 可以将 decimal.MinValue 转换为空字符串并返回的自定义 JsonConverter

c# - 'Newtonsoft.Json.. .' exists in both ' Blend\Newtonsoft.Json.dll' 和 'Solution\packages\...\

java - BSON 序列化器/反序列化器

json - 带有选项字段的 F# 记录在 Asp.Net WebApi 2.x 应用程序中未正确反序列化

java - 如何在 java 中迭代 bson 文档