Атрибуты DataMember в WCF не учитываются при копировании из списка в другой

Когда я копирую класс DataColumns в класс RatesOfPay, атрибуты DataMember в WCF больше не учитываются, когда я использую следующий код для копирования. Я хочу видеть результаты в порядке Step8, Step9, Step10, но я получаю Step10, Step8, Step9, поскольку атрибут Order игнорируется, а столбцы сортируются в алфавитном порядке. . Также атрибут EmitDefaultValue = false игнорируется, и я вижу шаги с нулевыми значениями.

List<DataColumns> source = new List<DataColumns>();
List<RatesOfPay> destination = new List<RatesOfPay>();

destination = source.Select(d => new RatesOfPay
{
    step8 = d.column8,
    step9= d.column9,
    step10 = d.column10
}).ToList();

public class DataColumns
{

    [DataMember(Order = 0, Name = "column8", EmitDefaultValue = false)]
    public string column8 { get; set; }

    [DataMember(Order = 1, Name = "column9", EmitDefaultValue = false)]
    public string column9 { get; set; }

    [DataMember(Order = 2, Name = "column10", EmitDefaultValue = false)]
    public string column10 { get; set; }
}

public class RatesOfPay
{

    [DataMember(Order = 0, Name = "Step8", EmitDefaultValue = false)]
    public string step8 { get; set; }

    [DataMember(Order = 1, Name = "Step9", EmitDefaultValue = false)]
    public string step9 { get; set; }

    [DataMember(Order = 2, Name = "Step10", EmitDefaultValue = false)]
    public string step10 { get; set; }
}

person Raj    schedule 16.03.2015    source источник
comment
Я думаю, вы неправильно понимаете, для чего нужен DataMember. Это не для упорядочивания свойств/полей в определяемом пользователем объекте. Он используется для предоставления информации о члене для использования DataContractSerializer. Если вы посмотрите на сериализованный результат (например, XML), вы увидите Step8, Step9 и Step10. Если вы посмотрите в отладчике, когда он десериализован, вы увидите его в алфавитном порядке ASCII.   -  person Tim    schedule 17.03.2015
comment
Аналогично, EmitDefaultValue указывает сериализатору выдать значение по умолчанию для типа данных. Это правда по умолчанию. Если вы установите для него значение false, любое свойство, имеющее нулевое значение (или значение по умолчанию для типов значений), не будет сериализовано, но останется в объекте. Взгляните на DataMemberAttribute Class на MSDN — есть несколько примеров, демонстрирующих, что к чему — но это все относится к сериализации.   -  person Tim    schedule 17.03.2015
comment
Большое спасибо за ваш комментарий. Изменение его на использование [XmlSerializerFormat] помогло!   -  person Raj    schedule 24.03.2015


Ответы (1)


Чтобы расширить мои комментарии, DataMember используется для указания DataContractSerializer, как сериализовать конкретный элемент.

Order сообщает DataContractSerializer, в каком порядке сериализовать/десериализовать элемент.

EmitDefaultValue сообщает DataContractSerialzier, следует ли выдавать значения по умолчанию (null для ссылочных типов, заданное значение для типов значений) при сериализации. Если установлено значение false, результатом не будет null — член будет опущен. Это правда по умолчанию.

Несколько примеров могут помочь проиллюстрировать это:

Во-первых, класс. Если вы посмотрите на класс в отладчике, свойства будут перечислены в алфавитном порядке ASCII, что означает, что шаг 10 будет указан первым. Так будет и column10.

Если вы посмотрите на сериализованный XML, вы можете увидеть что-то вроде этого:

<column8>abcd</column8>
<column9>defg</column9>
<column10>hijk</column10>

Если бы один из столбцов, скажем, column9, был нулевой строкой, вы бы увидели это (с EmitDefaultValue, установленным в false) при сериализации:

<column8>abcd</column8>
<column10>zzzz</column10>

EmitDefaultValue может немного сбивать с толку с точки зрения именования. И у него есть несколько действительно забавных взаимодействий с IsRequired.

person Tim    schedule 17.03.2015