views:

64

answers:

5

Hi, I have problems with serializing enum values.

Here is the code:

[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");

The result is:

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

Why the enum is not serialized? I use .NET Framework 2.0.

Thank you.

A: 

You can use the Xml.Serialization.XmlEnum attribute (see here) to decorate the values of the enum.

There is a blog post by Kurt Claeys here that might help as well.

TLiebe
I tried this but it didn't work.
etarvt
A: 

Hi,

Try putting [Flags] attribute on the enum.

regards,

Raut

rauts
That's absolutely irrelevant to serialization.
VladV
@vladv - while it might not apply here, there are times when [Flags] matters for serialisation. IMO a valid answer as something to check, especially thinking of the "long tail".
Marc Gravell
I agree with you. my Bad
rauts
+1  A: 

Do you see the same problem when you set the type to "Two" or "Three"? Is it because "One" is the default value and so can be assumed? It might be some artifact of loading this into an XmlDocument and then saving it with your code that you've not shown (TestWriteXml).

This slightly modified version of your code (I'm writing to a StringBuilder and then ToString'ing it at the end)...

    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());

... using the EXACT same types as you mention above appears to work fine. I get this at the console...

<?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" />

I didn't change the definition of REQUEST or the enum REQUESTTypetype.

Martin Peck
I was just doing the same thing and getting the same basic results. I think the problem is in your TestWriteXml function.
pstrjds
I just tried the example I gave here and it works fine. However my xml is much larger than this whith many derived elements and etc. and the serialization ignores every enum type in the result XML. Any idea which part of the code I should post to make things clearer?
etarvt
I would suggest starting with your example and add things back in until it no longer works. I would guess that somewhere down the line (child or grandchild class) is missing an attribute, or clearing something.
pstrjds
OK, thanks. I'll try.
etarvt
A: 

In your actual code, is the member:

  • public
  • read+write (for fields: not readonly; for properties: public get+set)
  • of a public type

?

All 3 must be true. For nested types, every parent type in the nesting must be public.

Additional things that would exclude it:

  • nullable and null
  • is if DefaultValue
  • a ShouldSerialize or Specified returned false
  • it is IxmlSerializable
Marc Gravell
Also, in the case of classes (not enums) there must be a public parameterless constructor.
Marc Gravell
A: 

I found what was wrong. For every enum type

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

I got this:

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

And in the code I should do this:

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

It works fine now. I should have post them in my question but I did not pay attention to these "specified" members at all. Thanks for your replies.

etarvt