C# XmlSerializer反序列化License类报System.InvalidOperationException错误求助
C# XML反序列化报错
<LicenseBase xmlns=''> was not expected 解决方案 错误原因
序列化阶段你使用typeof(LicenseBase)构造XmlSerializer,生成的XML根节点固定为<LicenseBase>;反序列化阶段你使用typeof(T)(此处T为派生类License)构造XmlSerializer,序列化器默认期望根节点名称和派生类名License匹配,因此触发类型不匹配异常。
解决方案(按推荐度排序)
方案1(最推荐):统一序列化时使用实际派生类类型
修改WriteLicense方法中的序列化器构造逻辑,直接用泛型参数T的类型构造序列化器,生成的XML根节点会自动匹配派生类名,无需修改反序列化逻辑:
// 替换原有的序列化器构造代码 XmlSerializer serializer = new XmlSerializer(typeof(T));
此方案生成的XML根节点为<License>,和反序列化时的期望完全匹配,同时适配后续新增的其他LicenseBase派生类。
方案2:统一反序列化时使用基类类型
修改ReadLicense方法中的序列化器构造逻辑,和序列化阶段保持一致,使用基类类型构造并传入已知派生类列表,反序列化后强转为T即可:
// 替换原有的序列化器构造代码 XmlSerializer serializer = new XmlSerializer(typeof(LicenseBase), new[] { typeof(License) });
该方案无需调整序列化逻辑,适合需要保留<LicenseBase>根节点名称的场景。
方案3:给派生类指定根节点别名
如果需要保留现有XML结构不变,可以给派生类添加XmlRoot特性,指定其序列化/反序列化时识别的根节点名称为LicenseBase:
[XmlRoot("LicenseBase")] public class License : LicenseBase { [Browsable(false)] public bool Test { get; set; } }
优化建议
可以直接给基类LicenseBase添加XmlInclude特性标记所有派生类,后续构造XmlSerializer时无需再手动传入已知类型数组:
[Serializable] [XmlInclude(typeof(License))] // 新增这行,有其他派生类也依次添加 public abstract class LicenseBase { // 原有逻辑保持不变 }
内容的提问来源于stack exchange,提问作者Michael Insberg
相关产品推荐
相关产品推荐

