Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - what attributes to use to support serializing using both XMLSerializer and DataContractSerializer?

I have some simple POCO object:

public class ProductCategoryDTO
{
        public string Name { get; set; }
        public DateTime ModifiedDate { get; set; }
}

As sometimes field order is important (for example, if sending to Infopath forms), I need to keep element order when serializing.

And now I am confused, what attributes I should use for the class and for each field. I know that:

  • DataContractSerializer uses [DataContract] and [DataMember(Order = n)]
  • XMLSerializer uses [Serializable] and [XmlElementAttribute(Order = n)].

Then what attributes to use if I want to support both XMLSerializer and DataContractSerializer, so it can used in both WCF or ASP. web services?

like image 763
JustAMartin Avatar asked Dec 30 '22 07:12

JustAMartin


1 Answers

Strictly speaking, you don't need to use any attributes for either ;-p It used to be that DataContractSerializer would demand [DataContract] / [DataMember] (and they absolutely should be used), but you can use it without (but it then acts in a very dubious way similar to BinaryFormatter). Likewise, XmlSerializer doesn't need anything unless you want to control things. There are, however, some differences you should note:

  • XmlSerializer demands (and uses) a public parameterless constructor; DataContractSerializer doesn't use a constructor (at all). So watch out for that, and don't (for WCF) rely on code in the ctor - if you have necessary init code, use a serialization callback for WCF.
  • XmlSerializer demands either public fields (yeuch) or public properties with both get and set (even for lists); DataContractSerializer will happily work against private members, properties with (for example) a public get and private set, and collections without a `set (as long as your type initialises it).
  • XmlSerializer demands public types; IIRC DataContractSerializer is less fussy

So yes; you can support both serializers, and you can add any number of attributes in parallel, but note the above if you want total compatibility.

Another option is to just use XmlSerializer; you can configure WCF to use XmlSerializer by using [XmlSerialzerFormat]. Both options support inheritance, via [XmlInclude] and [KnownType].

Finally, note that if you implement IXmlSerializable, this takes precedence over either, but it hard to get right. Don't do that unless you have to.

like image 168
Marc Gravell Avatar answered Feb 08 '23 17:02

Marc Gravell