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

使用Refit解析包含对象与空数组的怪异API响应问题

解决JSON数组到C#对象的解析问题

问题原因

你的API响应最外层是数组类型([{}, []]),但你定义的TableDetailResponse是键值对对象类型,两者结构不匹配,导致解析失败。序列化器无法自动将数组映射到包含Table和Errors两个属性的对象上。

解决方案

这里提供三种可行的处理方式:

方式一:直接解析为数组后手动转换

修改Refit接口的返回类型为object[],调用后手动解析数组元素:

public interface SOJOSurveyService
{
    [Get("/survey/{id}")]
    Task<object[]> QueryQuestionsByFlow([AliasAs("id")] string questionID);
}

调用示例:

var responseArray = await service.QueryQuestionsByFlow("your-id");
// 解析第一个元素为QuestionTable
var questionTable = JsonConvert.DeserializeObject<QuestionTable>(responseArray[0].ToString());
// 第二个元素是空数组,直接转为List<object>
var errors = JsonConvert.DeserializeObject<List<object>>(responseArray[1].ToString());

方式二:使用ValueTuple匹配数组结构

利用C# ValueTuple直接匹配JSON数组的两个元素,序列化器会自动映射:

public interface SOJOSurveyService
{
    [Get("/survey/{id}")]
    Task<(QuestionTable Table, List<object> Errors)> QueryQuestionsByFlow([AliasAs("id")] string questionID);
}

调用示例:

var (table, errors) = await service.QueryQuestionsByFlow("your-id");
// 直接使用table和errors即可

方式三:自定义JSON转换器(推荐)

创建自定义转换器,将数组结构映射到你原有的TableDetailResponse对象,这样可以保留原有的类结构:

  1. 实现自定义转换器:
public class TableDetailResponseConverter : JsonConverter<TableDetailResponse>
{
    public override TableDetailResponse ReadJson(JsonReader reader, Type objectType, TableDetailResponse existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonArray = JArray.Load(reader);
        return new TableDetailResponse
        {
            Table = jsonArray[0].ToObject<QuestionTable>(serializer),
            Errors = jsonArray[1].ToObject<List<object>>(serializer)
        };
    }

    public override void WriteJson(JsonWriter writer, TableDetailResponse value, JsonSerializer serializer)
    {
        var jsonArray = new JArray();
        jsonArray.Add(JToken.FromObject(value.Table, serializer));
        jsonArray.Add(JToken.FromObject(value.Errors, serializer));
        jsonArray.WriteTo(writer);
    }
}
  1. 在TableDetailResponse类上标记转换器:
[JsonConverter(typeof(TableDetailResponseConverter))]
public class TableDetailResponse
{
    public QuestionTable Table { get; set; }
    public List<object> Errors { get; set; }
}
  1. 保持原Refit接口不变即可正常解析:
public interface SOJOSurveyService
{
    [Get("/survey/{id}")]
    Task<TableDetailResponse> QueryQuestionsByFlow([AliasAs("id")] string questionID);
}

内容的提问来源于stack exchange,提问作者manaclan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 21:17:55