You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# MAUI中RestResponse使用JSON.NET反序列化失败问题求助

解决C# MAUI中RestResponse反序列化MongoDB风格JSON的问题

问题根源

你的反序列化失败主要有两个原因:

  1. 响应JSON的顶层结构是包含documents数组的对象,而非直接的数组,直接反序列化成List<object>会完全不匹配结构
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 16:32:23