枚举类型的XML序列化

9

我在序列化枚举值方面遇到了问题。

以下是代码:

[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public class REQUEST
{
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string ID;

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public REQUESTTypetype Type;
}

public enum REQUESTTypetype
{
    One,
    Two,
    Three,
    Four,
}

...

REQUEST request = new REQUEST();
request.ID = "1234";
request.Type = REQUESTTypetype.One;

XmlDocument doc = new XmlDocument();
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
XmlSerializer xs = new XmlSerializer(typeof(REQUEST));
xs.Serialize(sw, request_group);
ms.Position = 0;
doc.Load(ms);
TestWriteXml(doc, @"C:\xml_test.xml");

结果是:
<?xml version="1.0" encoding="utf-8" ?> 
<REQUEST ID="1234" />

为什么枚举类型不能被序列化?我使用的是.NET Framework 2.0。
谢谢。

1
我猜测你的代码中缺少了一些东西,你正在序列化“xs.Serialize(sw, request_group)”,但是你为“request”设置了值。request_group的定义是什么,它是否有设置类型? - pstrjds
它应该是“请求”,我只是稍微改了一下名称。 - etarvt
1
你的TestWriteXml函数的代码是什么? - pstrjds
公共静态函数 TestWriteXml(XmlDocument xml, string filename) { FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fileStream); sw.WriteLine(xml.InnerXml); sw.Flush(); sw.Close(); } - etarvt
VladV,我尝试使用[System.Xml.Serialization.XmlElement()]而不是[System.Xml.Serialization.XmlAttributeAttribute()],但没有结果。 - etarvt
5个回答

17

我找出了问题所在。对于每种枚举类型

[System.Xml.Serialization.XmlAttributeAttribute()]
public REQUESTTypetype Type;

我得到了这个:

[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool TypeSpecified;

而在代码中,我应该这样做:

request.Type = REQUESTTypetype.One;
request.TypeSpecified = true;

现在它运行得很好。 我应该将它们发布在我的问题中,但我完全没有注意这些“指定”的成员。 谢谢你的回复。


2

当您将类型设置为“Two”或“Three”时,是否看到了相同的问题?这是因为“One”是默认值,因此可以假定吗?可能是将其加载到XmlDocument中,然后使用您未显示的代码(TestWriteXml)保存它的某些工件。

这是您代码的稍微修改版本(我正在编写一个StringBuilder,然后在最后ToString'ing它)...

    REQUEST request = new REQUEST();
    request.ID = "1234";
    request.Type = REQUESTTypetype.One;


    StringBuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    XmlSerializer xs = new XmlSerializer(typeof(REQUEST));
    xs.Serialize(sw, request);
    Console.WriteLine(sb.ToString());

使用与您上面提到的完全相同的类型似乎可以正常工作。我在控制台上得到了这个...

<?xml version="1.0" encoding="utf-16"?>
<REQUEST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http:/
/www.w3.org/2001/XMLSchema" ID="1234" Type="One" />

我没有改变REQUEST的定义或枚举REQUESTType类型。

我刚刚也在做同样的事情,得到了相同的基本结果。我认为问题出在你的TestWriteXml函数中。 - pstrjds
我刚刚尝试了我在这里提到的例子,它运行良好。然而,我的 XML 比此示例要大得多,有许多派生元素等等,而序列化会忽略结果 XML 中的每个枚举类型。您有任何想法应该发布哪部分代码以使事情更清晰? - etarvt
我建议从你的示例开始,逐步添加内容,直到它不再起作用。我猜想在某个地方(子类或孙子类)缺少了一个属性,或者清除了某些东西。 - pstrjds

0

你可以使用 Xml.Serialization.XmlEnum 属性(在这里查看)来修饰枚举的值。

还有 Kurt Claeys 的一篇博客文章 在这里 也可能会有所帮助。


0
在您实际的代码中,该成员是否为:
  • 公共的
  • 可读写的(对于字段:非只读;对于属性:具有公共的get和set)
  • 属于公共类型的

?

所有3个条件都必须为真。对于嵌套类型,嵌套中的每个父类型都必须是公共的。

排除它的其他事项:

  • 可空和空
  • 如果为DefaultValue,则为is
  • 一个ShouldSerialize或Specified返回false
  • 它是IxmlSerializable

此外,在类(而非枚举)的情况下,必须有一个公共的无参构造函数。 - Marc Gravell

-3
尝试在枚举上放置[Flags]属性。

6
这与序列化完全无关。 - VladV
@vladv - 虽然这可能不适用于此处,但在序列化时有时[Flags]很重要。 在我看来,作为需要检查的内容,尤其是考虑到“长尾”的情况,这是一个有效的答案。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接