如何用System.Text.Json处理值类型不统一的JSON字段?
优雅处理非标准化JSON的number字段(System.Text.Json)
针对JSON中number字段类型不统一的问题,最简洁可靠的方案是自定义Json转换器,让它自动兼容字符串、数值、空字符串三种场景,无需多次反序列化或捕获异常。
方案1:将number反序列化为string类型
如果需要保留原始数字的字符串形式(比如带前导零的"001"),可以用以下转换器:
自定义转换器实现
using System; using System.Text.Json; using System.Text.Json.Serialization; public class FlexibleNumberConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.TokenType switch { JsonTokenType.String => reader.GetString()?.Trim() ?? string.Empty, JsonTokenType.Number => reader.TryGetInt64(out var longVal) ? longVal.ToString() : reader.GetDouble().ToString(), _ => string.Empty }; } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { // 序列化时可统一转为数值或保持字符串,按需调整 if (long.TryParse(value, out var num)) writer.WriteNumberValue(num); else writer.WriteStringValue(value); } }
修改实体类
给number字段标记转换器属性:
public class JsonLiveryDetails { public string skinname { get; set; } public string drivername { get; set; } public string country { get; set; } public string team { get; set; } [JsonConverter(typeof(FlexibleNumberConverter))] public string number { get; set; } public int? priority { get; set; } }
使用方式
正常调用反序列化即可:
// 兼容任意一种JSON格式 var json1 = @"{""number"": ""0""}"; var json2 = @"{""number"": 125}"; var json3 = @"{""number"": """"}"; var details1 = JsonSerializer.Deserialize<JsonLiveryDetails>(json1); // number = "0" var details2 = JsonSerializer.Deserialize<JsonLiveryDetails>(json2); // number = "125" var details3 = JsonSerializer.Deserialize<JsonLiveryDetails>(json3); // number = ""
方案2:将number反序列化为int?类型
如果需要直接转为可空整数(空字符串对应null),可以用以下转换器:
自定义转换器实现
using System; using System.Text.Json; using System.Text.Json.Serialization; public class FlexibleIntConverter : JsonConverter<int?> { public override int? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.TokenType switch { JsonTokenType.String => string.IsNullOrWhiteSpace(reader.GetString()) ? null : int.TryParse(reader.GetString()?.Trim(), out var val) ? val : null, JsonTokenType.Number => reader.GetInt32(), _ => null }; } public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options) { if (value.HasValue) writer.WriteNumberValue(value.Value); else writer.WriteNullValue(); } }
修改实体类
public class JsonLiveryDetails { // 其他字段不变 [JsonConverter(typeof(FlexibleIntConverter))] public int? number { get; set; } public int? priority { get; set; } }
使用效果
var details1 = JsonSerializer.Deserialize<JsonLiveryDetails>(@"{""number"": ""0""}"); // number = 0 var details2 = JsonSerializer.Deserialize<JsonLiveryDetails>(@"{""number"": 125}"); // number = 125 var details3 = JsonSerializer.Deserialize<JsonLiveryDetails>(@"{""number"": """"}"); // number = null
内容的提问来源于stack exchange,提问作者alexddf
相关产品推荐
相关产品推荐

