使用RestSharp反序列化JSON时,如何处理本该为数组却返回空对象的字段?
使用RestSharp反序列化JSON时,如何处理本该为数组却返回空对象的字段?
这种后端返回格式“不按常理出牌”的情况真的挺闹心的,我之前对接第三方接口时也碰到过一模一样的问题——明明定义的是数组字段,没数据时却返回个空对象,直接导致反序列化报错。你试的NullValueHandling和MissingMemberHandling确实解决不了这个问题,因为这俩是处理null值和缺失字段的,而咱们现在遇到的是类型不匹配(预期数组,实际是对象)的问题,得用自定义转换器来搞定。
方案一:自定义JsonConverter(最靠谱的通用解法)
我们可以写一个通用的Json转换器,专门处理这种“可能是数组,也可能是空对象”的字段。这个转换器的逻辑很简单:在反序列化时,如果遇到空对象,就返回一个空数组;如果是正常的数组,就按常规方式反序列化。
先写转换器的代码(基于Newtonsoft.Json,因为你提到了JsonSerializerSettings,应该用的是这个序列化库):
public class EmptyObjectToArrayConverter<T> : JsonConverter { public override bool CanConvert(Type objectType) { // 只处理目标类型的数组 return objectType.IsArray && objectType.GetElementType() == typeof(T); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var token = JToken.Load(reader); // 如果是空对象,返回空数组 if (token.Type == JTokenType.Object && !token.HasValues) { return Array.CreateInstance(typeof(T), 0); } // 如果是正常数组,按常规逻辑反序列化 else if (token.Type == JTokenType.Array) { return token.ToObject(objectType, serializer); } // 额外处理:万一后端还会返回单个对象的情况,直接转成单元素数组 else { var item = token.ToObject<T>(serializer); var array = Array.CreateInstance(typeof(T), 1); array.SetValue(item, 0); return array; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 序列化时按正常数组处理即可 serializer.Serialize(writer, value); } }
有两种使用方式可选:
- 局部标记(给特定属性加特性)
在你的实体类的数组属性上加上转换器标记:
public class YourRootClass { [JsonConverter(typeof(EmptyObjectToArrayConverter<Person>))] public Person[] Person { get; set; } } public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string MiddleName { get; set; } public string Birthdate { get; set; } }
- 全局注册(所有同类型数组自动生效)
如果接口里有很多这种格式不一致的字段,不想一个个加特性,可以把转换器全局注册到RestClient的序列化配置里:
var client = new RestClient(); var settings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new EmptyObjectToArrayConverter<Person>() } }; client.UseNewtonsoftJson(settings);
方案二:使用System.Text.Json的兼容配置(RestSharp 107+版本适用)
如果你现在用的是RestSharp默认的System.Text.Json序列化器,可以写一个基于该库的转换器,逻辑和上面类似:
public class EmptyObjectToArrayConverter<T> : JsonConverter<T[]> { public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.StartObject) { // 跳过空对象的所有内容,直接返回空数组 while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) { } return Array.Empty<T>(); } else if (reader.TokenType == JsonTokenType.StartArray) { return JsonSerializer.Deserialize<T[]>(ref reader, options); } else { // 兼容单个对象返回的情况 var item = JsonSerializer.Deserialize<T>(ref reader, options); return new[] { item }; } } public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, options); } }
然后全局注册到RestClient:
var client = new RestClient(); var options = new JsonSerializerOptions(); options.Converters.Add(new EmptyObjectToArrayConverter<Person>()); client.UseSystemTextJson(options);
为什么你之前的设置没用?
再补充一句,你之前试的NullValueHandling.Ignore是告诉序列化器忽略null值的字段,MissingMemberHandling.Ignore是忽略类里没有定义的JSON字段,这俩都解决不了“对象和数组类型不匹配”的核心问题,所以才会依然报错。
内容来源于stack exchange
相关产品推荐
相关产品推荐

