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

XML反序列化为C#类遇XmlSports未预期错误,求解决

问题

现有如下XML内容:

<XmlSports CreateDate="2022-12-04T17:47:53.5569879Z"> 
  <Sport Name="eSports" ID="2357"> 
    <Event Name="NBA2K, NBA Blitz League" ID="66838" IsLive="false" CategoryID="9357"> 
      <Match Name="LA Clippers (THA KID) Esports - Milwaukee Bucks (SHARPSHOOTER)" ID="2711992" StartDate="2022-12-04T17:36:00" MatchType="Live"> 
        <Bet Name="Money Line" ID="43859970" IsLive="true"> 
          <Odd Name="1" ID="297613016" Value="2.26"/> 
          <Odd Name="2" ID="297613021" Value="1.58"/> 
        </Bet> 
        <Bet Name="Spread" ID="43859969" IsLive="true"> 
          <Odd Name="1" ID="297614398" Value="1.83" SpecialBetValue="2.5"/> 
          <Odd Name="2" ID="297614399" Value="1.90" SpecialBetValue="2.5"/> 
        </Bet> 
        <Bet Name="Total" ID="43859971" IsLive="true"> 
          <Odd Name="Over" ID="297613741" Value="1.86" SpecialBetValue="140.5"/> 
          <Odd Name="Under" ID="297613740" Value="1.86" SpecialBetValue="140.5"/> 
        </Bet> 
      </Match> 
    </Event> 
    <Event Name="FIFA, GT League" ID="62647" IsLive="false" CategoryID="8212"> 
      ... <!-- 内容过长省略 -->
    </Event> 
  </Sport>
</XmlSports>

目标是将其反序列化为C#类,现有类定义如下:

Sport类

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [Serializable, XmlRoot("Sport")]
    public class Sport
    {
        [XmlElement("ID")]
        public int ID { get; set; }
        [XmlElement("Name")]
        public string Name { get; set; }
        [XmlElement("Event")]
        public List<Event> Events { get; set; }
    }
}

Event类

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [XmlType("Event")]
    public class Event
    {
        [XmlElement("ID")]
        public int ID { get; set; }
        [XmlElement("Name")]
        public string Name { get; set; }
        [XmlElement("CategoryID")]
        public int CategoryID { get; set; }
        [XmlElement("IsLive")]
        public bool IsLive { get; set; }
        [XmlElement("Match")]
        public List<Match> Matches { get; set; }
    }
}

另有Odd、Match和Bet类,反序列化代码如下:

private static async Task<Sport> DeserializeXMLToObject()
{
    private static readonly string xmlUrl = @"*此处为实际URL*";
    XmlSerializer ser = new XmlSerializer(typeof(Sport));
    HttpClient client = new HttpClient();
    HttpResponseMessage response = client.GetAsync(xmlUrl).Result;
    string xml = "";
    if (response.IsSuccessStatusCode)
    {
        xml = response.Content.ReadAsStringAsync().Result;
    }
    Sport sport = new Sport();
    using(TextReader reader = new StringReader(xml))
    {
        sport = (Sport)ser.Deserialize(reader);
    }
    return sport;
}

执行sport = (Sport)ser.Deserialize(reader);时触发错误:

InnerException = {"<XmlSports xmlns=''> was not expected."}

此前曾创建XmlSports类,但因Entity Framework代码优先迁移时无法为该类生成主键而移除,改为将Sport设为根类。尝试从XML生成XSD文件也失败,寻求解决建议。


解决方案

1. 重新添加XmlSports根类并规避EF主键问题

错误核心是XML根元素是XmlSports,但你用XmlSerializer(typeof(Sport))反序列化,导致根元素不匹配。必须添加对应根类,同时用[NotMapped]标记让EF不为它生成数据库表,避免主键问题:

using System.Xml.Serialization;
using System.ComponentModel.DataAnnotations.Schema;

namespace BettingDataAPI.Models
{
    [XmlRoot("XmlSports")]
    [NotMapped] // 告诉EF不要为这个类创建表
    public class XmlSports
    {
        [XmlAttribute("CreateDate")]
        public DateTime CreateDate { get; set; }

        [XmlElement("Sport")]
        public Sport Sport { get; set; }
    }
}

2. 修正类的XML序列化属性

你之前的类用了[XmlElement]对应XML子元素,但原XML中ID、Name等都是元素属性(比如<Sport Name="eSports" ID="2357">),需要改成[XmlAttribute]才能正确映射:

修正后的Sport类

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [XmlType("Sport")]
    public class Sport
    {
        [XmlAttribute("ID")]
        public int ID { get; set; }
        [XmlAttribute("Name")]
        public string Name { get; set; }
        [XmlElement("Event")]
        public List<Event> Events { get; set; }
    }
}

修正后的Event类

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [XmlType("Event")]
    public class Event
    {
        [XmlAttribute("ID")]
        public int ID { get; set; }
        [XmlAttribute("Name")]
        public string Name { get; set; }
        [XmlAttribute("CategoryID")]
        public int CategoryID { get; set; }
        [XmlAttribute("IsLive")]
        public bool IsLive { get; set; }
        [XmlElement("Match")]
        public List<Match> Matches { get; set; }
    }
}

示例Match类(参考修正)

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [XmlType("Match")]
    public class Match
    {
        [XmlAttribute("ID")]
        public int ID { get; set; }
        [XmlAttribute("Name")]
        public string Name { get; set; }
        [XmlAttribute("StartDate")]
        public DateTime StartDate { get; set; }
        [XmlAttribute("MatchType")]
        public string MatchType { get; set; }
        [XmlElement("Bet")]
        public List<Bet> Bets { get; set; }
    }
}

示例Bet类(参考修正)

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [XmlType("Bet")]
    public class Bet
    {
        [XmlAttribute("ID")]
        public int ID { get; set; }
        [XmlAttribute("Name")]
        public string Name { get; set; }
        [XmlAttribute("IsLive")]
        public bool IsLive { get; set; }
        [XmlElement("Odd")]
        public List<Odd> Odds { get; set; }
    }
}

示例Odd类(参考修正)

using System.Xml.Serialization;
namespace BettingDataAPI.Models
{
    [XmlType("Odd")]
    public class Odd
    {
        [XmlAttribute("ID")]
        public int ID { get; set; }
        [XmlAttribute("Name")]
        public string Name { get; set; }
        [XmlAttribute("Value")]
        public decimal Value { get; set; }
        [XmlAttribute("SpecialBetValue")]
        public decimal? SpecialBetValue { get; set; } // 可选属性用可空类型
    }
}

3. 修正反序列化代码的异步逻辑

原代码用.Result阻塞异步操作,容易引发死锁,改成正确的await写法:

private static async Task<Sport> DeserializeXMLToObject()
{
    var xmlUrl = @"*此处为实际URL*";
    var ser = new XmlSerializer(typeof(XmlSports)); // 改为序列化XmlSports类型
    using (var client = new HttpClient())
    {
        var response = await client.GetAsync(xmlUrl);
        if (!response.IsSuccessStatusCode)
        {
            return null; // 或处理错误情况
        }
        var xml = await response.Content.ReadAsStringAsync();
        using (var reader = new StringReader(xml))
        {
            var xmlSports = (XmlSports)ser.Deserialize(reader);
            return xmlSports.Sport;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:20:35