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

如何使用C#反序列化REST API返回JSON中的指定嵌套部分?

处理SOAP转JSON的嵌套响应反序列化问题

问题描述

我的C#程序调用REST API后,收到的响应是由SOAP XML转换而来的JSON格式,嵌套结构如下:

{
  "soap:Envelope": {
    "@xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/",
    "soap:Header": {
      "omni:To": "http://www.w3.org/2005/08/tset/usr",
      "omni:From": {
        "omni:Address": "https://myweb.test/1UNIW"
      },
      "omni:Action": "http://webservices.apitest.com/1UNIW",
      "omni:MessageID": "j00012",
      "omnii:Session": {
        "omnii:SecurityToken": "2S8BN3BPJMSHQK4OYKZRODFW3"
      }
    },
    "soap:Body": {
      "MyFunct": {
        "@xmlns": "http://xml.test.com/1UNIW",
        "replyInfo": {
          "status": {
            "tierTypeInfo": "IJK"
          }
        },
        "FleetIndex": [
          {
            "groupOfObject": {
              "propDetail": {},
              "itemDetails": [
                {
                  "ietmInformation": {
                    "itemDateTime": {
                      "dateOfDeparture": "270224"
                    },
                    "itemNumber": "2057"
                  }
                }
              ]
            }
          }
        ],
        "serviceCoverageInfoGrp": {
          "itemNumberInfo": {
            "itemNumber": {
              "number": "1"
            }
          }
        }
      }
    }
  }
}

我尝试用Newtonsoft.Json反序列化:

var v = JsonConvert.DeserializeObject<ResultResponse>(jsonmessage);

但仅针对FleetIndex创建了ResultResponse类,反序列化失败,寻求最佳处理方案。


解决方案

核心问题

反序列化失败的根源是ResultResponse只匹配了FleetIndex节点,但JSON是多层嵌套结构(根节点为soap:Envelope,目标数据在soap:Body.MyFunct.FleetIndex),必须匹配完整层级或直接提取目标节点。

方案一:完整映射层级类结构

按JSON的嵌套关系创建对应C#类,用[JsonProperty]特性处理带冒号的键名:

// 根节点类
public class SoapEnvelope
{
    [JsonProperty("soap:Envelope")]
    public EnvelopeContent Envelope { get; set; }
}

public class EnvelopeContent
{
    [JsonProperty("@xmlns:soap")]
    public string XmlnsSoap { get; set; }
    [JsonProperty("soap:Header")]
    public SoapHeader Header { get; set; }
    [JsonProperty("soap:Body")]
    public SoapBody Body { get; set; }
}

public class SoapBody
{
    [JsonProperty("MyFunct")]
    public MyFunctContent MyFunct { get; set; }
}

public class MyFunctContent
{
    [JsonProperty("@xmlns")]
    public string Xmlns { get; set; }
    [JsonProperty("FleetIndex")]
    public List<FleetIndexItem> FleetIndex { get; set; }
    // 其他不需要的字段可忽略,Newtonsoft.Json会自动跳过
}

// FleetIndex相关类
public class FleetIndexItem
{
    [JsonProperty("groupOfObject")]
    public GroupOfObject GroupOfObject { get; set; }
}

public class GroupOfObject
{
    [JsonProperty("propDetail")]
    public object PropDetail { get; set; } // 空对象用object接收
    [JsonProperty("itemDetails")]
    public List<ItemDetail> ItemDetails { get; set; }
}

public class ItemDetail
{
    [JsonProperty("ietmInformation")] // 注意JSON中的拼写(少了字母t),必须严格匹配
    public ItemInformation ItemInformation { get; set; }
}

public class ItemInformation
{
    [JsonProperty("itemDateTime")]
    public ItemDateTime ItemDateTime { get; set; }
    [JsonProperty("itemNumber")]
    public string ItemNumber { get; set; }
}

public class ItemDateTime
{
    [JsonProperty("dateOfDeparture")]
    public string DateOfDeparture { get; set; }
}

反序列化时:

var envelope = JsonConvert.DeserializeObject<SoapEnvelope>(jsonmessage);
var targetFleetData = envelope.Envelope.Body.MyFunct.FleetIndex;

方案二:直接提取目标节点(轻量方案)

如果仅需要FleetIndex数据,可使用JObject直接定位,避免创建大量冗余类:

// 仅需创建FleetIndex相关的类(同方案一中的FleetIndexItem及下级类)
var jObj = JObject.Parse(jsonmessage);
var fleetIndex = jObj["soap:Envelope"]["soap:Body"]["MyFunct"]["FleetIndex"]
    .ToObject<List<FleetIndexItem>>();

关键注意事项

  • 严格匹配JSON键名:比如原JSON中的ietmInformation(拼写错误),类的JsonProperty必须完全一致。
  • 空对象处理:propDetail这类空对象可用object或自定义空类接收,避免反序列化报错。
  • 确保类属性为public,Newtonsoft.Json无法访问私有属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:55:38