.net – 使用XmlSerializer将空的xml属性值反序列化为可空的int属性

前端之家收集整理的这篇文章主要介绍了.net – 使用XmlSerializer将空的xml属性值反序列化为可空的int属性前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我从第三方得到一个XML,我需要反序列化成C#对象。此xml可能包含带有整数类型或空值的属性:attr =“11”或attr =“”。我想反序列化这个属性值到类型为nullable integer的属性。但XmlSerializer不支持反序列化为可空类型。以下测试代码在使用InvalidOperationException创建XmlSerializer期间失败{“反映类型为”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:

There is an error in XML document (1,16).

任何人可以建议如何反序列化属性与空值为可空类型(作为null)同时反序列化非空的属性值为整数?有这里的任何技巧,所以我不必手动地做每个字段反序列化(实际上有很多他们)?

更新后,从ahsteele的注释:

> Xsi:nil attribute

据我所知,这个属性只适用于XmlElementAttribute – 此属性指定元素没有内容,无论是子元素还是主体文本。但我需要找到XmlAttributeAttribute的解决方案。反正我不能改变xml,因为我没有控制它。
> bool *Specified property

属性仅在属性值非空或属性缺失时工作。当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:

Cannot serialize member ‘Value’ of type TestConsoleApplication.NullableInt.

XmlAttribute/XmlText cannot be used to encode types implementing 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接口。

目前,它看起来像我必须实现IXmlSerializable为整个Element类(它是大),没有简单的解决方法

这应该工作:
[XmlIgnore]
public int? Age { get; set; }

[XmlElement("Age")]
public string AgeAsText
{
  get { return (Age.HasValue) ? Age.ToString() : null; } 
  set { Age = !string.IsNullOrEmpty(value) ? int.Parse(value) : default(int?); }
}

猜你在找的XML相关文章