C#反序列化XML时Controller列表为空的解决办法
XML反序列化时Controller列表始终为空问题排查与修复
问题描述
尝试反序列化包含3个Controller条目(每个条目下含network列表)的Networks对象,但Controller列表始终为空,已查阅相关帖子未找到解决办法。
定义的类代码
using System; using System.Collections.Generic; using System.Xml.Serialization; namespace TestXML { [Serializable()] [XmlRoot("Networks")] public class Networks { [XmlArray(ElementName = "Controller")] [XmlArrayItem("NetworkController")] public List<NetworkController> Controller { get; set; } [XmlAttribute("computer")] public string computer { get; set; } [XmlAttribute("GlobalFPPProxy")] public string GlobalFPPProxy { get; set; } [XmlAttribute("GlobalForceLocalIP")] public string GlobalForceLocalIP { get; set; } } [XmlType("NetworkController")] public class NetworkController { [XmlAttribute(AttributeName = "Id")] public string Id { get; set; } [XmlAttribute(AttributeName = "Name")] public string Name { get; set; } [XmlArray(ElementName = "network")] [XmlArrayItem("NetworkControllerNetwork")] public List<NetworkControllerNetwork> network { get; set; } } [XmlType("NetworkControllerNetwork")] public class NetworkControllerNetwork { [XmlAttribute(AttributeName = "ComPort")] public string ComPort { get; set; } [XmlAttribute("BaudRate")] public int BaudRate { get; set; } [XmlAttribute("NetworkType")] public string NetworkType { get; set; } [XmlAttribute("MaxChannels")] public int MaxChannels { get; set; } } }
反序列化代码
private readonly string xml = @"<Networks computer=""DESKTOP-281OHFP"" GlobalFPPProxy=""GlobalFPPProxy"" GlobalForceLocalIP=""GlobalForceLocalIP""> <Controller Id=""100"" Name=""Falcon F4V3 1""> <network ComPort=""192.168.1.254"" BaudRate=""100"" NetworkType=""E131"" MaxChannels=""512""/> <network ComPort=""192.168.1.254"" BaudRate=""101"" NetworkType=""E131"" MaxChannels=""512""/> <network ComPort=""192.168.1.254"" BaudRate=""102"" NetworkType=""E131"" MaxChannels=""512""/> <network ComPort=""192.168.1.254"" BaudRate=""103"" NetworkType=""E131"" MaxChannels=""512""/> <network ComPort=""192.168.1.254"" BaudRate=""104"" NetworkType=""E131"" MaxChannels=""512""/> <network ComPort=""192.168.1.254"" BaudRate=""105"" NetworkType=""E131"" MaxChannels=""512""/> </Controller> <Controller Id=""1"" Name=""Serial_""> <network ComPort=""COM4"" BaudRate=""250000"" NetworkType=""DMX"" MaxChannels=""1""/> </Controller> <Controller Id=""2"" Name=""Null_""> <network NetworkType=""NULL"" MaxChannels=""1""/> </Controller> </Networks> "; private void GenerateXML_Click(object sender, EventArgs e) { Networks result = new(); string inputString = xml; XmlDocument doc = new (); doc.LoadXml(inputString); XmlSerializer serializer = new (typeof(Networks)); StringReader rdr = new(doc.InnerXml); if (rdr is not null) { if (serializer is not null) result = serializer.Deserialize(rdr) as Networks; //richTextBox1.Text = result.Controller.ToString(); rdr.Close(); } }
问题原因及修复方案
1. 修正Networks类的Controller属性序列化特性
当前代码使用[XmlArray]和[XmlArrayItem],这要求XML结构为<Controller><NetworkController>...</NetworkController></Controller>,但你的XML是直接将多个<Controller>作为Networks的子节点,没有外层数组容器。需替换为[XmlElement]:
// 替换原XmlArray相关特性 [XmlElement("Controller")] public List<NetworkController> Controller { get; set; }
2. 修正NetworkController类的network属性序列化特性
同理,XML中每个Controller下是直接的多个<network>节点,无外层容器,需替换特性:
// 替换原XmlArray相关特性 [XmlElement("network")] public List<NetworkControllerNetwork> network { get; set; }
3. 简化反序列化代码(可选)
无需先加载XmlDocument,直接读取原始字符串即可,同时使用using自动释放资源:
private void GenerateXML_Click(object sender, EventArgs e) { Networks result; XmlSerializer serializer = new(typeof(Networks)); using (StringReader rdr = new StringReader(xml)) { result = serializer.Deserialize(rdr) as Networks; } // 验证:此时result.Controller.Count应为3 }
额外注意事项
- XML节点/属性名称与类属性名称需严格匹配(大小写敏感)
- 若XML中存在可能缺失的数值属性(如部分network节点无BaudRate),建议将对应属性改为可空类型
int?,避免反序列化抛出异常
内容的提问来源于stack exchange,提问作者SS4077
相关产品推荐
相关产品推荐

