C # - какие атрибуты использовать для поддержки сериализации с использованием XMLSerializer и DataContractSerializer? - PullRequest
4 голосов
/ 19 декабря 2009

У меня есть простой объект POCO:

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

Поскольку иногда важен порядок полей (например, при отправке в формы Infopath), мне нужно сохранять порядок элементов при сериализации.

А теперь я запутался, какие атрибуты мне следует использовать для класса и для каждого поля. Я знаю, что:

  • DataContractSerializer использует [DataContract] и [DataMember (Order = n)]
  • XMLSerializer использует [Serializable] и [XmlElementAttribute (Order = n)].

Тогда какие атрибуты использовать, если я хочу поддерживать как XMLSerializer, так и DataContractSerializer, чтобы его можно было использовать как в WCF, так и в ASP. веб-сервисы?

Ответы [ 3 ]

6 голосов
/ 19 декабря 2009

Строго говоря говоря, вам не нужно использовать какие-либо атрибуты для обоих ;-p Раньше DataContractSerializer требовало [DataContract] / [DataMember] ( и они абсолютно должны использоваться), но вы можете использовать его без (но тогда он действует очень сомнительно, как BinaryFormatter). Точно так же, XmlSerializer ничего не нужно , если вы не хотите что-то контролировать. Однако следует отметить некоторые отличия:

  • XmlSerializer требует (и использует) открытый конструктор без параметров; DataContractSerializer не использует конструктор (вообще). Так что следите за этим и не полагайтесь (для WCF) на код в ctor - если у вас есть необходимый код инициализации, используйте обратный вызов сериализации для WCF.
  • XmlSerializer требует либо публичных полей (да), либо публичных свойств с get и set (даже для списков); DataContractSerializer будет успешно работать с закрытыми членами, свойствами с (например) общедоступными get и частными set, а также коллекциями без набора `(если ваш тип его инициализирует).
  • XmlSerializer требует публичных типов; IIRC DataContractSerializer менее суетливый

Так что да; Вы можете поддерживать оба сериализатора, а также можете добавить любое количество атрибутов параллельно , но обратите внимание на вышесказанное, если вы хотите полной совместимости.

Другой вариант - просто использовать XmlSerializer; вы можете настроить WCF на использование XmlSerializer с помощью [XmlSerialzerFormat]. Оба варианта поддерживают наследование через [XmlInclude] и [KnownType].

Наконец, обратите внимание, что если вы реализуете IXmlSerializable, это имеет приоритет над любым, но это трудно понять правильно. Не делай этого, если не обязан.

3 голосов
/ 19 декабря 2009

Я не вижу никакой причины, по которой вы не можете поместить оба атрибута в свойства класса и члена, если это действительно необходимо. Не выглядит красиво, но если это работает для вас, это просто прекрасно!

[DataContract(Namespace="....")]
[XmlType]
public class ProductCategoryDTO
{
        [DataMember(Order=1)]
        [XmlElementAttribute(Order=1)]
        public string Name { get; set; }

        [DataMember(Order=2)]
        [XmlElementAttribute(Order=2)]
        public DateTime ModifiedDate { get; set; }
}
1 голос
/ 19 декабря 2009

Порядок элементов XML должен диктоваться WSDL, и вам не нужно об этом беспокоиться. Начиная с .NET 3.5 SP1 вам больше не нужно использовать DataContractAttribute и DataMemberAttribute . Сериализатор автоматически включает все общедоступные свойства. Что касается XmlSerializer , то SerializableAttribute не действует. Этот атрибут используется для двоичной сериализации BinaryFormatter . Итак, чтобы возобновить, вы можете оставить класс как POCO, выставить его в веб-сервисе WCF или ASP.NET и оставить клиентов использовать его в соответствии с WSDL.

...