C# MAUI中RestResponse使用JSON.NET反序列化失败问题求助
解决C# MAUI中RestResponse反序列化MongoDB风格JSON的问题
问题根源
你的反序列化失败主要有两个原因:
- 响应JSON的顶层结构是包含
documents数组的对象,而非直接的数组,直接反序列化成List<object>会完全不匹配结构 - JSON中包含MongoDB的特殊格式字段(如
$oid、$numberInt),默认的JsonConvert无法解析这些嵌套的类型标识
解决方案
1. 创建匹配JSON结构的实体类
先定义对应JSON层级的类,同时处理可选字段(部分对象缺少Role、UserId、Pass):
// 顶层响应类,对应JSON的根结构 public class ApiResponse { [JsonProperty("documents")] public List<UserDocument> Documents { get; set; } } // 单个用户文档类,匹配数组中的每个对象 public class UserDocument { [JsonProperty("_id")] public ObjectId Id { get; set; } [JsonProperty("Role")] public int? Role { get; set; } [JsonProperty("UserId")] public int? UserId { get; set; } [JsonProperty("Email")] public string Email { get; set; } [JsonProperty("Pass")] public string Pass { get; set; } }
2. 自定义转换器处理MongoDB特殊格式
针对$numberInt和$oid写自定义Json转换器,把嵌套结构转成C#基础类型:
// 处理MongoDB的$numberInt格式 public class MongoIntConverter : JsonConverter<int?> { public override int? ReadJson(JsonReader reader, Type objectType, int? existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartObject) { var jObj = JObject.Load(reader); var numberStr = jObj["$numberInt"]?.Value<string>(); if (int.TryParse(numberStr, out int result)) return result; } return null; } public override void WriteJson(JsonWriter writer, int? value, JsonSerializer serializer) { if (value.HasValue) { writer.WriteStartObject(); writer.WritePropertyName("$numberInt"); writer.WriteValue(value.Value.ToString()); writer.WriteEndObject(); } else writer.WriteNull(); } } // 处理MongoDB的$oid格式 public class ObjectIdConverter : JsonConverter<ObjectId> { public override ObjectId ReadJson(JsonReader reader, Type objectType, ObjectId existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.StartObject) { var jObj = JObject.Load(reader); var oidStr = jObj["$oid"]?.Value<string>(); if (!string.IsNullOrEmpty(oidStr) && ObjectId.TryParse(oidStr, out ObjectId result)) return result; } return ObjectId.Empty; } public override void WriteJson(JsonWriter writer, ObjectId value, JsonSerializer serializer) { writer.WriteStartObject(); writer.WritePropertyName("$oid"); writer.WriteValue(value.ToString()); writer.WriteEndObject(); } }
3. 修改反序列化代码
配置转换器后,正确解析顶层响应类:
request.AddBody(body); RestResponse response = await client.PostAsync(request); if (response.IsSuccessful) { try { var jsonSettings = new JsonSerializerSettings(); jsonSettings.Converters.Add(new MongoIntConverter()); jsonSettings.Converters.Add(new ObjectIdConverter()); // 先解析顶层响应,再取出documents列表 var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(response.Content, jsonSettings); var userList = apiResponse.Documents; // 这里可以正常使用userList了 } catch (Exception ex) { // 捕获异常用于调试,比如输出错误信息 Console.WriteLine($"反序列化失败: {ex.Message}"); } }
额外说明
- 如果你不需要MongoDB的
ObjectId类型,可以把Id字段改成string,并调整ObjectIdConverter的逻辑直接返回$oid的字符串值 - 可选字段用
int?(可空int)是因为部分JSON对象中缺少Role、UserId,避免反序列化时抛出缺失字段的异常
内容的提问来源于stack exchange,提问作者TechOverflow
相关产品推荐
相关产品推荐

