C# 无命名空间下XmlSerializer反序列化抽象类报错如何解决
问题根因
你遇到的抽象类反序列化报错,是因为默认XmlSerializer解析无命名空间XML中的xsi:type属性时,无法匹配到XmlInclude声明的派生类标识,误判为要直接实例化抽象类。
可行解决方案
方案1:修改派生类特性(改动最小,推荐)
给所有派生自ValueColorConverter的子类添加XmlType特性,显式指定命名空间为空即可,原有其余代码无需修改:
[Serializable] [XmlInclude(typeof(ValueColorConverter_Band))] [XmlInclude(typeof(ValueColorConverter_Gradient))] public abstract class ValueColorConverter { public abstract string Convert(double value); } [Serializable] [XmlType(Namespace = "")] // 新增这行,显式指定空命名空间 public class ValueColorConverter_Band : ValueColorConverter { public override string Convert(double value) { //do work return ""; } } [Serializable] [XmlType(Namespace = "")] // 新增这行,显式指定空命名空间 public class ValueColorConverter_Gradient : ValueColorConverter { public override string Convert(double value) { //do work return ""; } }
修改后你原有Main方法中的反序列化逻辑可直接正常运行。
方案2:不修改实体类,动态配置序列化规则
如果不能改动实体类的特性定义,可以在初始化XmlSerializer时通过XmlAttributeOverrides动态给派生类指定空命名空间:
void Main() { XElement config = XElement.Parse(@"<ValueColorConverter xsi:Type=""ValueColorConverter_Band"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""/>"); // 构造自定义序列化规则 XmlAttributeOverrides overrides = new XmlAttributeOverrides(); // 给Band子类指定空命名空间 XmlAttributes bandAttrs = new XmlAttributes(); bandAttrs.XmlType = new XmlTypeAttribute() { Namespace = "" }; overrides.Add(typeof(ValueColorConverter_Band), bandAttrs); // 给Gradient子类指定空命名空间 XmlAttributes gradientAttrs = new XmlAttributes(); gradientAttrs.XmlType = new XmlTypeAttribute() { Namespace = "" }; overrides.Add(typeof(ValueColorConverter_Gradient), gradientAttrs); XmlSerializer xs = new XmlSerializer(typeof(ValueColorConverter), overrides); var vcc = xs.Deserialize(config.CreateReader()) as ValueColorConverter; }
这个方案不需要修改原有实体类的定义,适合实体类不能随意改动的场景。
内容的提问来源于stack exchange,提问作者user17207709
相关产品推荐
相关产品推荐

