Управление сгенерированным XML для автоматических свойств - PullRequest
0 голосов
/ 29 ноября 2010

Может кто-нибудь объяснить, как управлять сгенерированным XML?

У меня есть простой тестовый класс, NumberService ...

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

Теперь, если я использую XmlSerializer для десериализации экземпляра, я получаю то, что ожидал ...

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

но я пытался отправить это, а Фидлер показывал ...

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

Возмущаясь, я читал, что это из-за моего использования автоматических свойств, и действительно, если я изменил на ...

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

    public int Number2 { get; set; }
}

действительно XML меняется на ...

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

Но, конечно, я не могу изменить _number1 на Number1, так как это конфликтует со свойством: - (

Так как же вы можете контролировать XML?

... и немного больше чтения ...

это касается контрактов на данные WCF

Ответы [ 3 ]

2 голосов
/ 29 ноября 2010

Это связано с тем, как DataContractSerializer обрабатывает элементы с примененным атрибутом Serializable .

При сопоставлении с атрибутом Serializable DataContractSerializer откладываетсясемантика, которую вы ожидаете при использовании экземпляра с реализацией IFormatter ;другими словами, он будет сериализовать базовые поля, используя имена полей в качестве ключей к данным.

Поскольку вы используете автоматически сгенерированные свойства, на самом деле вы видите имена автоматическисгенерированные поля, которые генерирует для вас компилятор.

Чтобы обойти это, вы должны применить атрибут DataContract к классу и атрибут DataMember к свойствам(и вы можете управлять именем, указав его в атрибуте, если хотите, чтобы оно отличалось от имени свойства).

У вас также есть возможность вообще не указывать атрибуты DataContract / DataMember и использовать POCO DataContract сериализация ;это предполагает, что у вас есть конструктор по умолчанию без параметров и только сериализация открытых свойств / полей.

1 голос
/ 30 ноября 2010

Вы должны удалить атрибут [Serializable].Он не используется сериализацией XML и неправильно передает сообщение сериализатору контракта данных.

0 голосов
/ 29 ноября 2010

Если вы используете только XmlSerialization, то вы можете использовать атрибуты из System.Xml.Serialization пространства имен для управления Xml-сериализацией, например XmlAttributeAttribute .

Если вы хотите использовать DataContractSerializer в своей службе Wcf, вам нужно пометить свой класс атрибутом DataContract и пометить все свойства атрибутом DataMember.

IMHO DataContractSerializer гораздо более продвинутый, чем старая XmlSerialization

...