Why doesn't WCF DataContract serialize its members alphabetically?

I have several DataContract

that are similar to this (shortened for brevity):

[DataContract(Name = "ItemDTO", Namespace = "http://foo.com/")]
public class ItemDTO : IExtensibleDataObject
{
    [DataMember(IsRequired = true)]
    public string Name { get; set; }

    [DataMember]
    public string Value { get; set; }

    [DataMember(IsRequired = true)]
    public int Id { get; set; }

    public ExtensionDataObject ExtensionData { get; set; }
}

      

I hadn't noticed serialized messages before, but after a recent change two things were done: I added a new property called ReturnCode

and ran CodeMaid " Refactor ", in alphabetical order of the property.

It now looks something like this:

[DataContract(Name = "ItemDTO", Namespace = "http://foo.com/")]
public class ItemDTO : IExtensibleDataObject
{
    public ExtensionDataObject ExtensionData { get; set; }

    [DataMember(IsRequired = true)]
    public int Id { get; set; }

    [DataMember(IsRequired = true)]
    public string Name { get; set; }

    [DataMember]
    public int ReturnCode { get; set; }

    [DataMember]
    public string Value { get; set; }
}

      

According to Microsoft's Data Order Contributor Order page, I figured I would ReturnCode

break the contract as the serializer inserts it before Value

, so I added the attribute value Order

assuming the original order was literal, which gives:

[DataContract(Name = "ItemDTO", Namespace = "http://foo.com/")]
public class ItemDTO : IExtensibleDataObject
{
    public ExtensionDataObject ExtensionData { get; set; }

    [DataMember(IsRequired = true, Order = 0)]
    public int Id { get; set; }

    [DataMember(IsRequired = true, Order = 1)]
    public string Name { get; set; }

    [DataMember(Order = 3)]
    public int ReturnCode { get; set; }

    [DataMember(Order = 2)]
    public string Value { get; set; }
}

      

This, however, made it possible to rule out that the deserialized members were out of order. I went back to the previous set of changes to all the changes and, of course, the original members of the order were not in alphabetical SOAP request (viewed through the Fiddler ), but following the original order, as expressed in the code, ie: Name

, Value

, Id

.

I am currently adding values Order

to all of my old DTO types to arrange them according to their previous, pre-alphabet, layout. What I would like to know is why coded order instead of alphabetical order was used by the serializer? Microsoft rules say:

Next in order are the current data types that do not have the Set property of the DataMemberAttribute, in alphabetical order .

Update:

After I added the values Order

to order the properties in their original order, I ran Fiddler again and it still uses order items literally encoded. In other words, for some reason, my WCF service completely ignores any serialization sequence logic and just orders the properties in the order they appear in the .cs file. In fact, the only way I have been able to serialize it correctly is by physically rearranging the properties of each type in their original order. It worked, but it's not recommended.

Update 2 - Solution:

Following the advice of Dracor, I added attributes [XmlElement(Order = 1)]

and XmlRootAttribute

in my DTO. The SOAP serialization DID ends after the order assigned by these attributes. I didn't think about it, but my service does actually use Castle DynamicProxy and so I am assuming that it is changing the serializer from DataContractSerializer

to XmlSerializer

.

+3


source to share


1 answer


Why don't you just use the XmlSerializer to serialize / deserialize XML? It is more forgiving than DataContractSerializer and works most of the time.



+2


source







All Articles