如何在C#中反序列化JSON时保留数组结构并转为double?
解决方案:保留嵌套数组结构同时将数值转为double
当然可以解决这个问题!你遇到的核心矛盾是:原生.NET反序列化会把JSON数值解析为decimal且保留object[]数组结构,但你需要double类型;而直接用Json.NET时,虽然数值能转成double,但数组会被解析为JArray而非原生的嵌套数组结构。下面给你两种实用的解决方案:
方案1:自定义JsonConverter(精准控制字段/类型)
这种方式可以针对特定字段(比如你的value字段)进行处理,既保留嵌套数组的object[]结构,又自动将所有数值类型从decimal转换为double,同时兼容其他JSON类型(字符串、布尔值等)。
自定义转换器代码
public class NumericToDoubleArrayConverter : JsonConverter { public override bool CanConvert(Type objectType) { // 匹配object类型(对应你的value字段)或数组类型 return objectType == typeof(object) || objectType.IsArray; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { switch (reader.TokenType) { case JsonToken.StartArray: // 递归处理嵌套数组,将JArray转换为object[] var elements = new List<object>(); while (reader.Read() && reader.TokenType != JsonToken.EndArray) { elements.Add(ReadJson(reader, typeof(object), null, serializer)); } return elements.ToArray(); case JsonToken.Integer: case JsonToken.Float: // 将JSON数值从decimal转换为double var decimalValue = serializer.Deserialize<decimal>(reader); return (double)decimalValue; default: // 其他类型(字符串、布尔值等)直接反序列化 return serializer.Deserialize(reader); } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 如果需要序列化回JSON,这里可以对应处理(按需实现) serializer.Serialize(writer, value); } }
应用转换器到你的类
假设你的数据模型类是这样的:
public class YourDataModel { // 给需要处理的字段添加转换器特性 [JsonConverter(typeof(NumericToDoubleArrayConverter))] public object Value { get; set; } }
反序列化示例
string json = "{\"Value\": [[123.45, 678.90], 101.11, \"test\", true]}"; YourDataModel result = JsonConvert.DeserializeObject<YourDataModel>(json); // 验证结果: // result.Value 是 object[],其中: // 第一个元素是 object[] 包含两个double值123.45和678.90 // 第二个元素是double值101.11 // 第三个元素是字符串"test",第四个是布尔值true
方案2:全局配置Json.NET(批量处理)
如果你希望整个应用中所有的decimal都自动转为double,同时让数组解析为object[]而非JArray,可以通过全局序列化设置实现。不过注意这种方式会影响所有反序列化操作,适合全局统一需求的场景。
全局设置代码
var serializerSettings = new JsonSerializerSettings { Converters = new List<JsonConverter> { // 处理decimal转double new JsonConverter() { CanConvert = type => type == typeof(decimal), ReadJson = (reader, type, existingValue, serializer) => { var decimalVal = serializer.Deserialize<decimal>(reader); return (double)decimalVal; }, WriteJson = (writer, value, serializer) => { serializer.Serialize(writer, (decimal)(double)value); } }, // 处理数组转object[]而非JArray new JsonConverter() { CanConvert = type => type == typeof(object), ReadJson = (reader, type, existingValue, serializer) => { if (reader.TokenType == JsonToken.StartArray) { var list = new List<object>(); while (reader.Read() && reader.TokenType != JsonToken.EndArray) { list.Add(serializer.Deserialize(reader, typeof(object))); } return list.ToArray(); } return serializer.Deserialize(reader, type); }, WriteJson = (writer, value, serializer) => { serializer.Serialize(writer, value); } } } }; // 反序列化示例 string json = "{\"Value\": [[123.45, 678.90], 101.11]}"; YourDataModel result = JsonConvert.DeserializeObject<YourDataModel>(json, serializerSettings);
为什么之前的尝试有问题?
- 原生.NET反序列化(比如System.Text.Json):默认会将JSON数值解析为
decimal以保证精度,数组则会被解析为object[],但无法自动转为double。 - 直接用Json.NET:当反序列化为
object类型时,数组会被默认解析为JArray(Json.NET的动态数组类型),而非原生的object[],这就是你丢失原有数组结构的原因。
以上两种方案都解决了这两个问题:既保留了原生的嵌套object[]结构,又将数值统一转换为double类型。
内容的提问来源于stack exchange,提问作者gregseth
相关产品推荐
相关产品推荐

