如何对chartlyrics.com返回的XML字符串执行反序列化操作
错误原因分析
你遇到的报错由两个核心问题共同导致:
- 多余的
[Serializable]特性:XmlSerializer序列化不需要该特性(该特性仅用于二进制序列化场景),在WinRT/UWP/MAUI Windows平台下,该特性会触发序列化器探测内部受保护的RuntimeClass类型,直接抛出访问权限错误。 - XML节点映射配置错误:chartlyrics接口返回的XML根节点就是
ArrayOfSearchLyricResult,你当前给内部列表加[XmlArray]的配置和接口返回结构不匹配,也会导致序列化器初始化失败。 - 部分.NET运行环境下
XmlSerializer对公共字段的支持存在兼容问题,推荐改为公共属性定义。 - 接口返回的XML带默认命名空间,实体类未配置命名空间映射也会导致反序列化失败。
修复方案
第一步:修改实体类定义
// 去掉[Serializable]特性,指定根节点映射和对应命名空间 [XmlRoot("ArrayOfSearchLyricResult", Namespace = "http://api.chartlyrics.com/")] public class SearchLyricResultCollection { // 根节点下直接是多个SearchLyricResult子节点,直接用XmlElement映射即可 [XmlElement("SearchLyricResult")] public List<SearchLyricResult> ListOfTracks { get; set; } } // 去掉[Serializable]特性,字段改为属性 public class SearchLyricResult { [XmlElement(ElementName = "TrackId")] public string TrackId { get; set; } [XmlElement(ElementName = "LyricChecksum")] public string LyricChecksum { get; set; } [XmlElement(ElementName = "LyricId")] public string LyricId { get; set; } [XmlElement(ElementName = "SongUrl")] public string SongUrl { get; set; } [XmlElement(ElementName = "ArtistUrl")] public string ArtistUrl { get; set; } [XmlElement(ElementName = "Artist")] public string Artist { get; set; } [XmlElement(ElementName = "Song")] public string Song { get; set; } [XmlElement(ElementName = "SongRank")] public string SongRank { get; set; } }
第二步:反序列化代码无需修改,直接运行即可
修改后创建XmlSerializer实例的报错会直接消失,反序列化可以正常读取接口返回的XML内容。
备选兼容方案(如果仍有问题)
如果项目运行环境对XmlSerializer兼容度低,可以改用XDocument直接解析XML,绕开序列化器的初始化问题:
var doc = XDocument.Parse(xml); XNamespace ns = "http://api.chartlyrics.com/"; var result = doc.Descendants(ns + "SearchLyricResult") .Select(x => new SearchLyricResult { TrackId = x.Element(ns + "TrackId")?.Value, LyricChecksum = x.Element(ns + "LyricChecksum")?.Value, LyricId = x.Element(ns + "LyricId")?.Value, SongUrl = x.Element(ns + "SongUrl")?.Value, ArtistUrl = x.Element(ns + "ArtistUrl")?.Value, Artist = x.Element(ns + "Artist")?.Value, Song = x.Element(ns + "Song")?.Value, SongRank = x.Element(ns + "SongRank")?.Value }).ToList();
内容的提问来源于stack exchange,提问作者Weissu
相关产品推荐
相关产品推荐

