System.Text.Json如何反序列化取值为空字符串或自定义类的字段
解决方案
你可以通过实现自定义JsonConverter<T>来适配这种接口返回值不统一的场景,核心逻辑是在反序列化时先判断目标字段的JSON类型,再做对应的转换处理:
步骤1:实现针对Tags类型的自定义转换器
using System.Text.Json; using System.Text.Json.Serialization; public class TagsConverter : JsonConverter<Tags> { public override Tags Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 若当前JSON值是字符串类型,判断是否为空字符串 if (reader.TokenType == JsonTokenType.String) { var value = reader.GetString(); if (string.IsNullOrEmpty(value)) { // 空字符串场景返回null,也可根据业务需求返回带空数组的Tags实例:return new Tags { Tag = Array.Empty<Tag>() }; return null; } } // 若为对象类型则正常反序列化 if (reader.TokenType == JsonTokenType.StartObject) { return JsonSerializer.Deserialize<Tags>(ref reader, options); } // 非预期类型可直接返回null或者抛出异常 return null; } public override void Write(Utf8JsonWriter writer, Tags value, JsonSerializerOptions options) { // 序列化逻辑保持默认即可 JsonSerializer.Serialize(writer, value, options); } }
步骤2:注册转换器
你可以选择两种注册方式:
- 仅对指定字段生效:在
Artist类的Tags属性上添加转换器特性public class Artist { [JsonConverter(typeof(TagsConverter))] public Tags Tags { get; set; } } - 全局生效:反序列化时传入包含转换器的配置项
var serializerOptions = new JsonSerializerOptions { Converters = { new TagsConverter() } }; var deserializedObject = JsonSerializer.Deserialize<Artist>(requestBody, serializerOptions);
通用扩展(可选)
如果该API还有其他字段也存在「空字符串代替空对象」的情况,你可以实现泛型版本的通用转换器,不用为每个类型单独实现:
public class EmptyStringToNullConverter<T> : JsonConverter<T> where T : class { public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String && string.IsNullOrEmpty(reader.GetString())) { return null; } return JsonSerializer.Deserialize<T>(ref reader, options); } public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }
使用时直接指定泛型类型即可:[JsonConverter(typeof(EmptyStringToNullConverter<Tags>))]
内容的提问来源于stack exchange,提问作者Thom
相关产品推荐
相关产品推荐

