Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Testing Newtonsoft.Json Binder
using UnityEngine;
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters;
using System.Linq;
using NUnit.Framework;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace SDD.Test.NewtonSoft {
[TestFixture]
[Category("Serializers")]
public class JsonSerializerBinderTest : UnitTest {
private JsonSerializerSettings serializerSettings = new JsonSerializerSettings() {
// http://www.newtonsoft.com/json/help/html/SerializationSettings.htm
// write $type for objects but not collections
TypeNameHandling = TypeNameHandling.Objects,
// leave off assembly details
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
// Ignored by Unity
Binder = new TypeNameHandler(),
};
private class TypeNameHandler : DefaultSerializationBinder {
public override void BindToName(Type serializedType, out string assemblyName, out string typeName) {
Debug.Log(string.Format("TypeNameHandler.BindToName(serializedType: {0} ...)", serializedType));
assemblyName = null;
typeName = serializedType.FullName;
}
public override Type BindToType(string assemblyName, string typeName) {
Debug.Log(string.Format("TypeNameHandler.BindToType(assemblyName{0}, typeName: {1})", assemblyName, typeName));
// From: FullSerializer.Internal.fsTypeLookup
// https://github.com/jacobdufault/fullserializer
Type type = null;
// Try a direct type lookup
type = Type.GetType(typeName);
if (type != null) {
return type;
}
// If we still haven't found the proper type, we can enumerate all of the loaded
// assemblies and see if any of them define the type
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
// See if that assembly defines the named type
type = assembly.GetType(typeName);
if (type != null) {
return type;
}
}
return null;
}
}
public class ModelA {
public string owner;
public int Score { get; set; }
}
public class ModelB : ModelA {
public string Id { get; set; }
}
[Test]
public void DeserializesPolymorphicTypes() {
ModelB modelB = new ModelB() { Id="B", owner = "TEST DATA", Score = 2 };
string json = JsonConvert.SerializeObject(value: modelB, formatting: Formatting.None, settings: serializerSettings);
Debug.Log(json);
Assert.True(Regex.IsMatch(json, @"\$type"));
Assert.False(Regex.IsMatch(json, @", Assembly\-CSharp"));
var model = JsonConvert.DeserializeObject(value: json, settings: serializerSettings);
Assert.True(model.GetType() == typeof(ModelB));
ModelB b = (ModelB) model;
Assert.True(b.Id == "B");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment