0

Can anyone explain how to control the XML generated ?

I have a simple test class, NumberService ...

[Serializable]
public class NumberService
{
    public int Number1 { get; set; }
    public int Number2 { get; set; }
}

Now if I use an XmlSerializer to deserialise an instance, I get what I expected ...

<NumberService>
  <Number1>23</Number1>
  <Number2>45</Number2>
</NumberService>

but I was attempting to send this and Fiddler was showing ...

<NumberService>
<_x003C_Number1_x003E_k__BackingField>10</_x003C_Number1_x003E_k__BackingField>
<_x003C_Number2_x003E_k__BackingField>2</_x003C_Number2_x003E_k__BackingField>
</NumberService>

Poking around I've read that this is because of my use of automatic properties, and indeed if I changed to ...

public class NumberService
{
    private int _number1;
    public int Number1
    {
        get { return _number1; }
        set { _number1 = value; }
    }

    public int Number2 { get; set; }
}

indeed the XML changes to ...

<NumberService>
<_number1>4</_number1>
<_x003C_Number2_x003E_k__BackingField>6</_x003C_Number2_x003E_k__BackingField>
</NumberService>

But of course I can't change _number1 to Number1 as it'd conflict with the property :-(

So how can you control the XML ?

... and a bit more reading ...

this is involving WCF data contracts

casperOne
  • 73,706
  • 19
  • 184
  • 253
SteveC
  • 15,808
  • 23
  • 102
  • 173
  • "Now if I use an XmlSerializer to *deserialise* an instance, I get what I expected ... `...`" Do you mean *serialize*? I thought serializing (in this context) was the process of encoding a memory data structure into XML. – LarsH Nov 29 '10 at 20:44
  • Err ... checking ... nope I do mean serialise using (var streamWriter = File.CreateText(f)) { serializer.Serialize(streamWriter, n); } – SteveC Nov 30 '10 at 07:58
  • So is this serialising or deserialising ?? ... I thought generating the XML from an instance was serialising it ! – SteveC Nov 30 '10 at 10:32

3 Answers3

2

This has to do with how the DataContractSerializer handles items with the Serializable attribute applied.

When confronted with the Serializable attribute, the DataContractSerializer will defer to the semantics that you would expect when using the instance with an IFormatter implementation; in other words, it will serialize the underlying fields using the names of the fields as the keys to the data.

Because you are using auto-generated properties, what you are seeing is actually the names of the auto-generated fields that the compiler generates for you.

In order to get around this, you should apply the DataContract attribute to the class and the DataMember attribute to the properties (and you can control the name by specifying it in the attribute if you want it to differ from the property name).

You also have the option of not specifying the DataContract/DataMember attributes at all and using POCO DataContract serialization; this assumes you have a default parameterless constructor along with only serializing public properties/fields.

casperOne
  • 73,706
  • 19
  • 184
  • 253
1

You should remove the [Serializable] attribute. It is not used by XML Serialization, and it is giving the wrong message to the Data Contract Serializer.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • Spot on ... removed that attribute and even without the [DataContract] and [DataMember] attributes, I got the expected format in Fiddler. So this tracks back to the link by casperOne about POCO DataContract serialisation ... every day I learn more – SteveC Nov 30 '10 at 10:30
0

If you are using just XmlSerialization then you can use attributes from System.Xml.Serialization namespace to control Xml-Serialization for example XmlAttributeAttribute.

If you wand to use DataContractSerializer in your Wcf service, you need to mark your class with DataContract attribute and mark all properties with DataMember attribute.

IMHO DataContractSerializer is much more advanced, than old XmlSerialization

The Smallest
  • 5,713
  • 25
  • 38