Skip to content

Instantly share code, notes, and snippets.

@rofr
Created September 4, 2017 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rofr/79d1485f5c05e734bf1550bf6e8c1f96 to your computer and use it in GitHub Desktop.
Save rofr/79d1485f5c05e734bf1550bf6e8c1f96 to your computer and use it in GitHub Desktop.
Failed attempt at a JsonConverter to intercept JsonToken.Integer, (which will default to Int64 when assigned to a property of type Object)
namespace Memstate.JsonNet
{
public class JsonObjectToIntegerConverter : JsonConverter
{
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//never called because CanWrite is false
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Integer)
{
long val = Convert.ToInt64(reader.Value);
if (val <= Byte.MaxValue && val >= Byte.MinValue) return (byte) val;
if (val <= short.MaxValue && val >= short.MinValue) return (short) val;
if (val <= int.MaxValue && val >= int.MinValue) return (int) val;
return val;
}
return serializer.Deserialize(reader);
}
public override bool CanRead => true;
public override bool CanConvert(Type objectType)
{
return true || objectType == typeof(object) ||
objectType == typeof(Int32) ||
objectType == typeof(Int64);
}
}
}
namespace Memstate.JsonNet
{
public class JsonSerializerAdapter : ISerializer
{
private readonly JsonSerializer _serializer;
public JsonSerializerAdapter()
{
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
IgnoreSerializableAttribute = true,
SerializeCompilerGeneratedMembers = true
},
PreserveReferencesHandling = PreserveReferencesHandling.None,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
MissingMemberHandling = MissingMemberHandling.Ignore,
CheckAdditionalContent = false
};
settings.Converters.Insert(0,new JsonObjectToIntegerConverter());
_serializer = JsonSerializer.Create(settings);
}
public object ReadObject(Stream serializationStream)
{
var streamReader = new StreamReader(serializationStream);
var line = streamReader.ReadLine();
var reader = new JsonTextReader(new StringReader(line));
return _serializer.Deserialize(reader);
}
public IEnumerable<T> ReadObjects<T>(Stream stream)
{
var streamReader = new StreamReader(stream);
var jsonReader = new JsonTextReader(streamReader);
jsonReader.SupportMultipleContent = true;
while (jsonReader.Read())
{
yield return _serializer.Deserialize<T>(jsonReader);
}
}
public void WriteObject(Stream serializationStream, object @object)
{
var streamWriter = new StreamWriter(serializationStream);
var writer = new JsonTextWriter(streamWriter);
_serializer.Serialize(writer, @object);
writer.Flush();
streamWriter.Flush();
}
}
}
namespace Memstate.Tests
{
public class SerializationTests
{
[Fact]
public void Int32_can_be_cloned()
{
int i = 42;
var serializer = new JsonSerializerAdapter();
var stream = new MemoryStream();
serializer.WriteObject(stream, i);
stream.Position = 0;
object o = serializer.ReadObject(stream);
//fails with Actual: Int64, Expected: Int32
Assert.IsType<int>(o);
}
[Fact]
public void Int64_can_be_cloned()
{
long i = 42;
var serializer = new JsonSerializerAdapter();
var stream = new MemoryStream();
serializer.WriteObject(stream, i);
stream.Position = 0;
object o = serializer.ReadObject(stream);
Assert.IsType<long>(o);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment