【问题标题】:Serialize enum as int将枚举序列化为 int
【发布时间】:2010-01-12 21:05:15
【问题描述】:

我希望通过 Web 服务返回以下类,其中包括枚举类型作为其成员之一。

[Serializable, XmlRoot("GeoCoordinate")]
public class GeoCoordinate
{
    public enum AccuracyLevel
    {
        Unknown = 0,
        Country = 1,
        Region = 2,
        SubRegion = 3,
        Town = 4,
        PostalCode = 5,
        Street = 6,
        Intersection = 7,
        Address = 8,
        Premise = 9
    }

    private AccuracyLevel _accuracy;

    // ... more members


    public AccuracyLevel Accuracy
    {
        get { return _accuracy; } 
        set { _accuracy = value;}
    }
}

这可以正常工作,但会以以下形式返回结果:

<!-- ... -->
<Accuracy>Unknown or Country or Region or SubRegion or Town or 
  PostalCode or Street or Intersection or Address or Premise</Accuracy>
<!-- ... -->

我希望它简单地返回一个整数,而不是代表枚举的字符串。这可以在不改变GeoCoordinate.Accuracy的类型的情况下完成吗?

【问题讨论】:

标签: .net enums xml-serialization


【解决方案1】:

虽然这是一个 hack,但我认为在这种情况下对每个枚举成员使用 XmlEnumAttribute 是最容易接受的。如果这个枚举更大,最好在 Accuracy 属性上使用XmlIgnore,并按照此问题的另一个答案中的说明向该类添加一个额外的 int 属性。

Usng XmlEnumAttribute 表示只需要修改枚举本身,无论在哪里使用都会像int一样将xml序列化。

    public enum AccuracyLevel
    {
        [XmlEnum("0")] Unknown = 0,
        [XmlEnum("1")] Country = 1,
        [XmlEnum("2")] Region = 2,
        [XmlEnum("3")] SubRegion = 3,
        [XmlEnum("4")] Town = 4,
        [XmlEnum("5")] PostalCode = 5,
        [XmlEnum("6")] Street = 6,
        [XmlEnum("7")] Intersection = 7,
        [XmlEnum("8")] Address = 8,
        [XmlEnum("9")] Premise = 9
    }

【讨论】:

【解决方案2】:

我相信您需要在枚举上使用[XmlIgnore],并创建第二个返回整数值的属性:

[XmlRoot("GeoCoordinate")]
public class GeoCoordinate
{
    public enum AccuracyLevel
    {
        Unknown = 0,
        Country = 1,
        Region = 2,
        SubRegion = 3,
        Town = 4,
        PostalCode = 5,
        Street = 6,
        Intersection = 7,
        Address = 8,
        Premise = 9
    }

    private AccuracyLevel _accuracy;

    // ... more members


    [XmlIgnore]
    public AccuracyLevel Accuracy
    {
        get { return _accuracy; } 
        set { _accuracy = value;}
    }

    [XmlElement("AccuracyLevel")]
    public int AccuracyLevelInt
    {
        get {return (int) AccuracyLevel;}
        set {AccuracyLevel = (AccuracyLevel) value;}
    }
}

请注意,XML 序列化程序不使用[Serializable]

另外,请注意AccuracyLevelInt 属性的实现可能不正确。我现在正在调查。

【讨论】:

  • 这可行,但我希望避免创建另一个属性(可能通过 GeoCoordinate.Accurate 上的 Xml 属性,但似乎这不存在。)
【解决方案3】:

[Serializable][DataContract] 装饰枚举。这两个属性之间存在一些差异,请务必检查一下(this blog post 可能会有所帮助)。并用[EnumMember] 标记各个枚举项。我从未检查过枚举在传输过程中的样子,但这样做将确保它到达另一端,并且如果您生成客户端代理,还将确保它被拾取。

【讨论】:

  • 这些选项似乎都不会改变该字段的序列化方式。
  • 是的,我认为 WCF 没有区别,但如果您要序列化为 XML,它会起作用吗?我欢迎任何人对差异进行简单的项目符号解释。
猜你喜欢
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 2012-02-27
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多