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

C#调用XML服务反序列化返回内容报根级数据无效错误

问题原因

反序列化报错的核心原因有两个:

  1. 该接口是传统ASMX服务,返回的XML根节点是带默认命名空间的<string>包装节点,你定义的实体类没有匹配这个外层结构,序列化器找不到预期根节点就会抛出根级别数据无效的错误。
  2. 你定义的业务实体没有配置XML序列化相关特性,即使手动剥掉外层包装,默认命名空间的匹配规则也可能导致属性值读取失败。
解决方案

方法1:剥离外层包装后反序列化(逻辑简单,推荐使用)

<string>是ASMX框架自动追加的通用返回包装,节点内部的XML才是你需要的业务数据,提取内部内容再反序列化即可。
首先给实体类补全XML序列化特性,指定节点匹配规则:

using System.Xml.Serialization;

[XmlRoot(ElementName = "Datos_de_INGC011_CAT_INDICADORECONOMIC", Namespace = "")]
public class Datos_de_INGC011_CAT_INDICADORECONOMIC
{
    [XmlElement(ElementName = "INGC011_CAT_INDICADORECONOMIC")]
    public INGC011_CAT_INDICADORECONOMIC IndicadorEconomico { get; set; }
}

public class INGC011_CAT_INDICADORECONOMIC
{
    [XmlElement(ElementName = "COD_INDICADORINTERNO")]
    public int CodigoIndicador { get; set; }
    
    [XmlElement(ElementName = "DES_FECHA")]
    public DateTime Fecha { get; set; }
    
    [XmlElement(ElementName = "NUM_VALOR")]
    public double Valor { get; set; }
}

拿到接口返回字符串后,先提取内层业务XML再执行反序列化:

using System.Xml;
using System.Xml.Serialization;

// 沿用你原有请求逻辑拿到returnedXml后,执行以下处理
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(returnedXml);
// 提取<string>节点包裹的真实业务XML内容
var negocioXml = xmlDoc.DocumentElement!.InnerXml;

var serializer = new XmlSerializer(typeof(Datos_de_INGC011_CAT_INDICADORECONOMIC));
using var lector = new StringReader(negocioXml);
var resultado = (Datos_de_INGC011_CAT_INDICADORECONOMIC)serializer.Deserialize(lector);

// 正常读取数据即可,比如resultado.IndicadorEconomico.Valor就是接口返回的650.1

方法2:补全外层包装实体,直接反序列化完整返回

如果你不想手动剥离节点,可以定义匹配外层<string>节点的实体,一次性完成反序列化:

[XmlRoot(ElementName = "string", Namespace = "http://ws.sdde.bccr.fi.cr")]
public class EnvoltorioRespuestaBccr
{
    [XmlElement(ElementName = "Datos_de_INGC011_CAT_INDICADORECONOMIC", Namespace = "")]
    public Datos_de_INGC011_CAT_INDICADORECONOMIC DatosIndicador { get; set; }
}
// Datos_de_INGC011_CAT_INDICADORECONOMIC、INGC011_CAT_INDICADORECONOMIC两个类的定义和方法1完全一致

反序列化时直接传入完整返回字符串即可:

var serializer = new XmlSerializer(typeof(EnvoltorioRespuestaBccr));
using var lector = new StringReader(returnedXml);
var resultado = (EnvoltorioRespuestaBccr)serializer.Deserialize(lector);
// 业务数据从resultado.DatosIndicador.IndicadorEconomico中获取
注意事项
  • 不要用.Result同步调用HttpClient,高并发场景下容易触发线程池死锁,建议把请求逻辑改成async/await异步写法。
  • 日期字段DES_FECHA带-06:00时区偏移,反序列化后会自动转换为程序运行环境的本地时间,如果你需要保留原始时区时间,可以把实体里的对应属性类型改成DateTimeOffset。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:42:28