XML字符串转SiteItem对象映射失败,请求排查问题
嘿,我一眼就看到两个核心问题导致你的反序列化失败,咱们一个个捋清楚:
1. XML序列化属性标记完全用反了
你的SiteItem类里用[XmlElement]标记IdSiteItem和ItemName,但看你给出的XML结构,这两个是SiteItem节点的属性(Attribute),不是子元素(Element)!比如<SiteItem IdSiteItem="8436" ItemName="demoweb" />里的IdSiteItem是节点的属性,不是<IdSiteItem>8436</IdSiteItem>这种子元素结构。
这是最关键的错误,必须把标记改成[XmlAttribute]:
[XmlRoot("SiteItem")] public class SiteItem : BaseEntity<SiteItem> { [XmlAttribute("IdSiteItem")] // 替换成XmlAttribute public int IdSiteItem { get; set; } [XmlAttribute("ItemName")] // 同样替换成XmlAttribute public string ItemName{ get; set; } // ... 其他代码 }
2. 手动切割XML字符串是灾难级操作
你现在用字符串替换、拆分的方式处理XML,完全忽略了XML的结构化特性,而且你的原始XML本身就有语法问题(比如第一个SiteItem没有闭合标签,还嵌套了其他SiteItem),这种手动处理很容易把XML搞成非法格式,XmlSerializer根本无法解析。
正确的做法是直接用.NET的XML解析类(比如XDocument或者XmlDocument)来处理整个XML字符串,而不是手动拆。
修正后的Populate方法示例
咱们重新写Populate方法,用XDocument来解析,步骤更严谨:
public override SiteItem Populate(DataRow entity) { var xmlString = entity["Column1"].ToString(); // 直接加载整个XML,XDocument会自动修复部分轻微语法错误 var doc = XDocument.Parse(xmlString); // 提取所有SiteItem节点(包括嵌套的;如果只需要顶层节点,就用doc.Root.Elements("SiteItem")) var siteItemElements = doc.Descendants("SiteItem"); foreach (var elem in siteItemElements) { // 方法1:直接从属性取值,比反序列化更高效 var siteItem = new SiteItem { IdSiteItem = int.Parse(elem.Attribute("IdSiteItem").Value), ItemName = elem.Attribute("ItemName")?.Value ?? string.Empty }; // 这里可以把siteItem加入集合或者做后续处理 // 例如:yourSiteItemList.Add(siteItem); // 方法2:如果一定要用XmlSerializer,把单个节点转成可读取的流再反序列化 using (var reader = elem.CreateReader()) { var serializer = new XmlSerializer(typeof(SiteItem)); var response = (SiteItem)serializer.Deserialize(reader); // 现在response应该能正确获取属性值了 } } // 注意:你原方法返回null,这里根据你的业务需求调整,比如返回第一个节点或者处理后的集合 return siteItemElements.Any() ? new SiteItem { IdSiteItem = int.Parse(siteItemElements.First().Attribute("IdSiteItem").Value), ItemName = siteItemElements.First().Attribute("ItemName")?.Value ?? string.Empty } : null; }
额外提醒:原始XML的语法问题
你的原始XML里有个不规范的节点:<SiteItem IdSiteItem=\"8436\" ItemName=\"demoweb\" >没有闭合,后面直接跟了嵌套的SiteItem,这属于非法XML。虽然XDocument.Parse会尝试修复这种问题,但最好还是让存储过程返回完全合法的XML(比如给这个节点加上闭合标签</SiteItem>),避免后续出现其他解析异常。
内容的提问来源于stack exchange,提问作者user9124444

