【发布时间】:2019-07-01 10:35:49
【问题描述】:
当我将一些 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;
}
}
}
但是结果会和之前的情况一样。
【问题讨论】:
-
或者,子类
JsonTextReader并返回int而不是long,如Overriding Default Primitive Type Handling in Json.Net 所示。虽然那里的答案已经过时了...... -
好的,我在Overriding Default Primitive Type Handling in Json.Net 中添加了一个new answer,它适用于更新的Json.NET 版本。
标签: c# json asp.net-web-api json.net asp.net-web-api2