Пока я десериализировал некоторые данные JSON в DataSet, результирующий набор данных может потерять свою схему столбцов.это означает, что когда я десериализую некоторый JSON, он заполняет набор данных объектами Int64, а не Int32.Я бы хотел, чтобы он выбрал Int32.
Я знаю, что Json.NET по умолчанию считывает целочисленные значения как Int64, потому что нет способа узнать, должно ли значение быть Int32 или Int64.
JsonSerializerSettings settings = new JsonSerializerSettings()
{
Converters = { new PrimitiveJsonConverter() },
};
DataSet myDataSet = JsonConvert.DeserializeObject<DataSet>(jsonString, settings);
Итак, я создал собственный JsonConverter для переопределения функций по умолчанию.
using DevExpress.XtraPrinting.Native.WebClientUIControl;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters;
using System.Text;
using System.Threading.Tasks;
using JsonConverter = Newtonsoft.Json.JsonConverter;
namespace CashlessAdmin.API.Handler
{
public sealed class PrimitiveJsonConverter : JsonConverter
{
readonly JsonSerializer defaultSerializer = new JsonSerializer();
public override bool CanConvert(Type objectType)
{
return objectType.IsIntegerTypes();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
if(Convert.ToInt64(reader.Value) < System.Int32.MaxValue)
{
return Convert.ToInt32(reader.Value);
}
return reader.Value;
case JsonToken.Float: // Accepts numbers like 4.00
case JsonToken.Null:
return defaultSerializer.Deserialize(reader, objectType);
default:
throw new JsonSerializationException(string.Format("Token \"{0}\" of type {1} was not a JSON integer", reader.Value, reader.TokenType));
}
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public static class JsonExtensions
{
public static bool IsIntegerTypes(this Type type)
{
type = Nullable.GetUnderlyingType(type) ?? type;
if (type == typeof(long)
|| type == typeof(ulong)
|| type == typeof(int)
|| type == typeof(uint)
|| type == typeof(short)
|| type == typeof(ushort)
|| type == typeof(byte)
|| type == typeof(sbyte)
|| type == typeof(System.Numerics.BigInteger))
return true;
return false;
}
}
}
Но результат будет таким же, как и в предыдущем случае.