I am trying to save content in my game with Json.net. with this resource I got my game saving to JSON but now I want to save it in the Bson format as I don't want my players to be able to easily edit the save files.
Here is the code works and is saving my game data to json.
File.WriteAllText(path, JsonConvert.SerializeObject(objectToSave, Formatting.Indented,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
}));
Here I am trying to save my game data in the bson format but I don't quite know how to turn off the ReferenceLoopHandling in the bson format.
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());
}
When I run this code I get the following error.
JsonSerializationException: Self referencing loop detected for property 'graph' with type 'StoryGraph'. Path 'nodes[0]'.
You can use the factory methods JsonSerializer.CreateDefault(JsonSerializerSettings)
or JsonSerializer.Create(JsonSerializerSettings)
to manufacture a serializer with your required settings, then serialize directly to a file using the following extension methods:
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);
}
}
}
And then serialize as follows:
BsonExtensions.SerializeToFile(objectToSave, path,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
Notes:
Be sure to use the same settings when deserializing.
BSON support was moved into its own package Newtonsoft.Json.Bson
in Json.NET 10.0.1
. In this version or later you should use BsonDataWriter
(and BsonDataReader
) as BsonWriter
has been made obsolete, and will eventually be removed.
serializer.ToString()
is not going to return the serialized BSON; instead use MemoryStream.ToArray()
, i.e.
File.WriteAllBytes(path, stream.ToArray());
However it's more efficient to stream directly to the file as shown in the extension methods above.
serializer.ReferenceLoopHandling.Equals(false);
is not the correct way to set the ReferenceLoopHandling
property in c#. Instead set it as if it were a field:
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
Demo fiddle here.