【发布时间】:2010-11-20 17:01:03
【问题描述】:
我从第 3 方获得了一个 xml,我需要将其反序列化为 C# 对象。此 xml 可能包含值为整数类型或空值的属性:attr=”11” 或 attr=””。我想将此属性值反序列化为可空整数类型的属性。但 XmlSerializer 不支持反序列化为可空类型。以下测试代码在创建 XmlSerializer 期间失败并出现 InvalidOperationException {"There was an error reflection type 'TestConsoleApplication.SerializeMe'."}.
[XmlRoot("root")]
public class SerializeMe
{
[XmlElement("element")]
public Element Element { get; set; }
}
public class Element
{
[XmlAttribute("attr")]
public int? Value { get; set; }
}
class Program {
static void Main(string[] args) {
string xml = "<root><element attr=''>valE</element></root>";
var deserializer = new XmlSerializer(typeof(SerializeMe));
Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
var result = (SerializeMe)deserializer.Deserialize(xmlStream);
}
}
当我将“Value”属性的类型更改为 int 时,反序列化失败并出现 InvalidOperationException:
XML 文档 (1, 16) 中存在错误。
任何人都可以建议如何将具有空值的属性反序列化为可空类型(作为 null),同时将非空属性值反序列化为整数?有什么技巧可以让我不必手动对每个字段进行反序列化(实际上有很多)?
在 ahsteele 发表评论后更新:
-
据我所知,此属性仅适用于 XmlElementAttribute - 此属性指定元素没有内容,无论是子元素还是正文。但我需要找到 XmlAttributeAttribute 的解决方案。无论如何,我无法更改 xml,因为我无法控制它。
-
此属性仅在属性值非空或缺少属性时有效。当 attr 具有空值 (attr='') 时,XmlSerializer 构造函数将失败(如预期的那样)。
public class Element { [XmlAttribute("attr")] public int Value { get; set; } [XmlIgnore] public bool ValueSpecified; } -
Custom Nullable class like in this blog post by Alex Scordellis
我尝试采用这篇博文中的课程来解决我的问题:
[XmlAttribute("attr")] public NullableInt Value { get; set; }但 XmlSerializer 构造函数失败并出现 InvalidOperationException:
无法序列化 TestConsoleApplication.NullableInt 类型的成员“值”。
XmlAttribute/XmlText 不能用于编码实现 IXmlSerializable 的类型}
-
丑陋的代理解决方案(我很惭愧我在这里写了这段代码:)):
public class Element { [XmlAttribute("attr")] public string SetValue { get; set; } public int? GetValue() { if ( string.IsNullOrEmpty(SetValue) || SetValue.Trim().Length <= 0 ) return null; int result; if (int.TryParse(SetValue, out result)) return result; return null; } }但我不想提出这样的解决方案,因为它破坏了我的类对其消费者的接口。我最好手动实现 IXmlSerializable 接口。
目前看来我必须为整个 Element 类(它很大)实现 IXmlSerializable 并且没有简单的解决方法......
【问题讨论】:
-
这个问题困扰了我十年。 2021年就没有简单的装饰器来解决这个问题了吗?
标签: .net xml serialization nullable