C#如何反序列化data字段类型动态的JSON数据?
解决System.Text.Json反序列化多类型data字段的问题
当前API返回两种格式的JSON响应:
- 错误响应(Type 1):
{ "type": "error", "data": "error message" }
- 成功响应(Type 2):
{ "type": "success", "data": [ { "id": 1, "title": "tortor at auctor urna nunc", "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit." }, { "id": 2, "title": "gravida rutrum quisque non tellus", "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit." } ] }
原ResponseData类将Data定义为string类型,反序列化Type 2响应时会抛出System.Text.Json.JsonException——因为JSON数组无法直接转换为字符串。需求是:无论data字段是字符串、数组还是整数,都将其转为JSON字符串存入responseData.Data,后续可再反序列化为DataList对象。
以下是两种可行解决方案:
方案一:自定义JsonConverter处理Data字段
编写自定义转换器,自动判断JSON值类型:如果是字符串直接返回,否则将该值序列为JSON字符串。
代码实现
using System.Text.Json; using System.Text.Json.Serialization; class ResponseData { [JsonPropertyName("type")] public string Type { get; set; } [JsonPropertyName("data")] [JsonConverter(typeof(AnyTypeToStringConverter))] public string Data { get; set; } } public class AnyTypeToStringConverter : JsonConverter<string> { public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) { return reader.GetString(); } using var document = JsonDocument.ParseValue(ref reader); return document.RootElement.GetRawText(); } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { if (JsonSerializer.Deserialize<JsonElement>(value) is var element) { element.WriteTo(writer); } else { writer.WriteStringValue(value); } } }
使用方式
保持原有反序列化代码即可:
var response = await httpClient.GetAsync(url); var responseData = await response.Content.ReadFromJsonAsync<ResponseData>(); Debug.WriteLine(responseData.Data); // 后续反序列化DataList if (responseData.Type == "success") { var dataList = JsonSerializer.Deserialize<DataList>(responseData.Data); // 处理dataList逻辑 }
方案二:先反序列化为JsonElement再转换
通过中间类接收响应,将data字段用JsonElement类型暂存,再手动转为JSON字符串。
代码实现
using System.Text.Json; // 中间过渡类,用JsonElement接收任意类型的data class ResponseDataInterim { [JsonPropertyName("type")] public string Type { get; set; } [JsonPropertyName("data")] public JsonElement Data { get; set; } } // 反序列化流程 var response = await httpClient.GetAsync(url); var interimData = await response.Content.ReadFromJsonAsync<ResponseDataInterim>(); var responseData = new ResponseData { Type = interimData.Type, Data = interimData.Data.GetRawText() }; Debug.WriteLine(responseData.Data); // 后续反序列化DataList if (responseData.Type == "success") { var dataList = JsonSerializer.Deserialize<DataList>(responseData.Data); // 处理dataList逻辑 }
两种方案均可实现需求:Type 1的data直接以字符串存入,Type 2的数组转为JSON字符串存入,后续能正常反序列化为DataList对象。
内容的提问来源于stack exchange,提问作者Cheng
相关产品推荐
相关产品推荐

