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

如何在C#中处理API返回的两种异构响应(Newtonsoft.Json)

处理API响应中message字段多类型的问题

针对API返回的message字段在成功时为对象、失败时为字符串的情况,有以下几种可行的处理方案:

方案一:先解析为JObject再按需处理

先将响应字符串反序列化为JObject,通过status字段判断结果类型后,再分别处理message字段:

var responseJObject = JObject.Parse(iziDataKtpOcrResponse);
string status = responseJObject["status"].ToString();

if (status == "OK")
{
    var successResponse = new IziDataKtpOcrResponseMessage
    {
        Status = status,
        message = responseJObject["message"].ToObject<IziDataKtpOcrResponseMessageData>()
    };
    // 执行成功业务逻辑
}
else if (status == "FAIL")
{
    string errorMessage = responseJObject["message"].ToString();
    // 处理失败场景,比如记录错误、提示用户等
}

方案二:自定义Json转换器适配多类型字段

通过编写自定义转换器,让模型的message字段同时支持对象和字符串两种类型:

步骤1:编写自定义转换器

public class MessageConverter : JsonConverter<IziDataKtpOcrResponseMessageData>
{
    public override IziDataKtpOcrResponseMessageData ReadJson(JsonReader reader, Type objectType, IziDataKtpOcrResponseMessageData existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 处理字符串类型的message(失败场景)
        if (reader.TokenType == JsonToken.String)
        {
            return new IziDataKtpOcrResponseMessageData
            {
                ErrorMessage = reader.Value.ToString()
            };
        }
        // 处理对象类型的message(成功场景)
        else if (reader.TokenType == JsonToken.StartObject)
        {
            return serializer.Deserialize<IziDataKtpOcrResponseMessageData>(reader);
        }
        throw new JsonException("message字段类型不符合预期");
    }

    public override void WriteJson(JsonWriter writer, IziDataKtpOcrResponseMessageData value, JsonSerializer serializer)
    {
        // 序列化时根据是否有错误信息选择输出格式(可选,根据需求实现)
        if (!string.IsNullOrEmpty(value.ErrorMessage))
        {
            writer.WriteValue(value.ErrorMessage);
        }
        else
        {
            serializer.Serialize(writer, value);
        }
    }
}

步骤2:修改数据模型

在原有模型基础上新增错误信息字段,并给message属性标记转换器:

public class IziDataKtpOcrResponseMessageData
{
    // 原有业务字段
    public string name { get; set; }
    public string id { get; set; }
    public string pob { get; set; }
    public string dob { get; set; }
    public string gender { get; set; }
    public string address { get; set; }
    public string rt { get; set; }
    public string rw { get; set; }
    public string village { get; set; }
    public string district { get; set; }
    public string religion { get; set; }
    public string marital_status { get; set; }
    public string work { get; set; }
    public string nationnality { get; set; }
    public string city { get; set; }
    public string province { get; set; }

    // 新增错误信息字段
    public string ErrorMessage { get; set; }
}

public class IziDataKtpOcrResponseMessage
{
    public string Status { get; set; }

    [JsonConverter(typeof(MessageConverter))]
    public IziDataKtpOcrResponseMessageData message { get; set; }
}

步骤3:正常反序列化并处理

var response = JsonConvert.DeserializeObject<IziDataKtpOcrResponseMessage>(iziDataKtpOcrResponse);
if (response.Status == "OK")
{
    // 使用response.message中的业务数据
}
else if (response.Status == "FAIL")
{
    string errorMsg = response.message.ErrorMessage;
    // 处理错误逻辑
}

方案三:使用动态类型(dynamic)

这种方式代码简洁,但缺乏类型检查,适合快速测试或小型项目:

dynamic response = JsonConvert.DeserializeObject(iziDataKtpOcrResponse);
string status = response.status;

if (status == "OK")
{
    // 直接访问response.message.name、response.message.id等字段
}
else if (status == "FAIL")
{
    string errorMsg = response.message;
    // 处理错误
}

各方案优缺点对比

  • 方案一:灵活度高,无需修改现有模型,适合简单场景;缺点是需要手动拆分反序列化步骤。
  • 方案二:类型安全,代码结构清晰,适合长期维护的项目;缺点是需要编写额外的转换器代码。
  • 方案三:代码最简洁,但运行时无类型校验,容易出现未捕获的错误,不推荐在大型项目中使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:32:07