我正试图用Json.net保存游戏中的内容。使用此资源,我将游戏保存到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: Self referencing loop detected for property 'graph' with type 'StoryGraph'. Path 'nodes[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支持已转移到Json.NET
10.0.1
中自己的包Newtonsoft.Json.Bson
中。在此版本或更高版本中,您应该使用BsonDataWriter
(和BsonDataReader
(,因为BsonWriter
已过时,并且最终将被删除。serializer.ToString()
不会返回已序列化的BSON;而是使用MemoryStream.ToArray()
,即File.WriteAllBytes(path, stream.ToArray());
但是,如上面的扩展方法所示,直接流式传输到文件更有效。
serializer.ReferenceLoopHandling.Equals(false);
不是在c#中设置ReferenceLoopHandling
属性的正确方法。相反,将其设置为一个字段:serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
请参阅:使用属性(C#编程指南(。
在这里演示小提琴。
您也可以直接设置序列化程序:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// Fix: Ignore loops
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
...
这为我解决了Unity C#上下文中的问题。