.NET Core中如何通过XmlAttributes重写XmlChoiceIdentifierAttribute特性
解决方案
核心原因
重写XmlSerializer配置时,默认读取的XmlAttributes不会自动继承原属性上的XmlChoiceIdentifierAttribute,且该属性公开接口为只读,无法直接赋值,导致序列化校验不通过报错。
可用方案:通过反射为XmlChoiceIdentifier属性赋值
XmlAttributes的XmlChoiceIdentifier属性的setter为internal级别,可通过反射手动赋值你构造的XmlChoiceIdentifierAttribute实例,完整实现代码如下:
using System.Reflection; using System.Xml.Serialization; // 1. 构造序列化重写配置对象 var overrides = new XmlAttributeOverrides(); // 2. 处理带XmlChoiceIdentifier的Item属性 var itemAttributes = new XmlAttributes(); // 保留/重写原有的XmlElement配置,可根据需求调整Order等参数 itemAttributes.XmlElements.Add(new XmlElementAttribute("PersonaFisica", typeof(string)) { Order = 0 }); itemAttributes.XmlElements.Add(new XmlElementAttribute("PersonaGiuridica", typeof(string)) { Order = 0 }); // 构造XmlChoiceIdentifier特性实例 var choiceAttr = new XmlChoiceIdentifierAttribute("ItemElementName"); // 反射赋值XmlChoiceIdentifier属性 var choiceProp = typeof(XmlAttributes).GetProperty( "XmlChoiceIdentifier", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); choiceProp.SetValue(itemAttributes, choiceAttr); // 将配置加入重写规则 overrides.Add(typeof(CUAA), nameof(CUAA.Item), itemAttributes); // 3. 处理对应的标识属性ItemElementName,取消XmlIgnore var identifierAttrs = new XmlAttributes(); identifierAttrs.XmlIgnore = false; identifierAttrs.XmlElements.Add(new XmlElementAttribute { Order = 1 }); overrides.Add(typeof(CUAA), nameof(CUAA.ItemElementName), identifierAttrs); // 4. 用重写配置构造XmlSerializer即可正常使用 var serializer = new XmlSerializer(typeof(CUAA), overrides);
注意事项
XmlChoiceIdentifierAttribute的MemberName参数必须和对应的标识属性名完全一致,不能出现拼写错误- 必须为标识属性(示例中的
ItemElementName)设置XmlIgnore = false,否则序列化时会因找不到标识属性报错 - 如果是批量处理大量自动生成的SOAP代理类,可以写通用反射逻辑,自动读取类属性上原有的
XmlChoiceIdentifierAttribute、XmlElementAttribute等配置,调整Order后再写入重写规则即可。
内容的提问来源于stack exchange,提问作者Daniele Accattoli
相关产品推荐
相关产品推荐

