using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class PreferInt32JsonTextReader : JsonTextReader
public PreferInt32JsonTextReader(TextReader reader) : base(reader) { }
public override bool Read()
if (TokenType == JsonToken.Integer
&& ValueType == typeof(long)
if (value <= int.MaxValue && value >= int.MinValue)
var newValue = checked((int)value);
SetToken(TokenType, newValue, false);
public static class JsonExtensions
public static T PreferInt32DeserializeObject<T>(string jsonString, JsonSerializerSettings settings = null)
using (var sw = new StringReader(jsonString))
using (var jsonReader = new PreferInt32JsonTextReader(sw))
return JsonSerializer.CreateDefault(settings).Deserialize<T>(jsonReader);
public enum TestShortEnum : short
public enum TestLongEnum : ulong
public static void Test()
Console.WriteLine("These tests will not work unless the current JSON version ({0}) is greater that or equal to 10.0.1.\n",
typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Done.");
TestDeserialize<int>(JsonConvert.SerializeObject(int.MaxValue), typeof(int));
TestDeserialize<int>(JsonConvert.SerializeObject(int.MinValue), typeof(int));
TestDeserialize<int>(json, typeof(int));
TestDeserialize<object>(json, typeof(int));
TestDeserialize<long>(json, typeof(long));
TestDeserialize<ulong>(json, typeof(ulong));
TestDeserialize<JToken>(json, typeof(JValue));
TestDeserialize<TestEnum>(json, typeof(TestEnum));
TestDeserialize<TestShortEnum>(json, typeof(TestShortEnum));
TestDeserialize<TestLongEnum>(json, typeof(TestLongEnum));
TestDeserialize<short>(json, typeof(short));
TestDeserialize<byte>(json, typeof(byte));
Console.WriteLine("\nDone with tests.");
private static void Test9914333()
object[] variousTypes = new object[] { 3.14m, 10, "test" };
string jsonString = JsonConvert.SerializeObject(variousTypes);
var settings = new JsonSerializerSettings
FloatParseHandling = FloatParseHandling.Decimal,
object[] asObjectArray = JsonExtensions.PreferInt32DeserializeObject<object[]>(jsonString, settings);
Assert.IsTrue(variousTypes.Select(o => o == null ? null : o.GetType()).SequenceEqual(asObjectArray.Select(o => o == null ? null : o.GetType())));
static void TestDataSet()
var json = @"{ ""Table"": [ { ""UserId"": 1, ""IsActive"": true, ""IsAdmin"": true, ""UserGroup"": ""Cashless Admin"", ""UserWithGroupName"": ""adminuser (CA)"", ""GroupName"": ""CA"" } ] }";
using (var sw = new StringReader(json))
using (var jsonReader = new JsonTextReader(sw))
var set = JsonSerializer.CreateDefault().Deserialize<DataSet>(jsonReader);
Assert.IsTrue(set.Tables.Count == 1);
var table = set.Tables[0];
Assert.IsTrue(table.Columns["UserId"].DataType == typeof(long));
using (var sw = new StringReader(json))
using (var jsonReader = new PreferInt32JsonTextReader(sw))
var set = JsonSerializer.CreateDefault().Deserialize<DataSet>(jsonReader);
Assert.IsTrue(set.Tables.Count == 1);
var table = set.Tables[0];
Assert.IsTrue(table.Columns["UserId"].DataType == typeof(int));
private static void TestSimple(string json)
using (var sw = new StringReader(json))
using (var jsonReader = new PreferInt32JsonTextReader(sw))
while (jsonReader.Read())
Console.WriteLine("{0}: {1} (type {2})", jsonReader.TokenType, jsonReader.Value, jsonReader.ValueType);
if (jsonReader.TokenType == JsonToken.Integer)
Assert.IsTrue(jsonReader.Value.GetType() == typeof(int));
public List<T> Array { get; set; }
private static void TestDeserialize<T>(string json, Type expectedType)
using (var sw = new StringReader(json))
using (var jsonReader = new PreferInt32JsonTextReader(sw))
var item = JsonSerializer.CreateDefault().Deserialize<T>(jsonReader);
Console.WriteLine("Primitive declared type {0}: value {1} (actual type {2})", typeof(T), item, item.GetType());
Assert.IsTrue(item.GetType() == expectedType);
Assert.IsTrue(JToken.DeepEquals(JToken.Parse(json), JToken.FromObject(item)));
var arrayJson = @"{""Array"" : [" + json + "]}";
using (var sw = new StringReader(arrayJson))
using (var jsonReader = new PreferInt32JsonTextReader(sw))
var root = JsonSerializer.CreateDefault().Deserialize<TestRoot<T>>(jsonReader);
Assert.IsTrue(root.Array != null && root.Array.Count == 1);
Console.WriteLine("Array item declared type {0}: value {1} (actual type {2})", typeof(T), root.Array[0], root.Array[0].GetType());
Assert.IsTrue(root.Array[0].GetType() == expectedType);
Assert.IsTrue(JToken.DeepEquals(JToken.Parse(arrayJson), JToken.FromObject(root)));
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");