Различают ли WCF и DataContractSerializer сериализованные типы коллекций CollectionDataContract по-разному? - PullRequest
5 голосов
/ 30 ноября 2010

У меня есть действительно простой настроенный тип коллекции, который наследуется от List <> и использует CollectionDataContract.

Когда я использую DataContractSerializer.WriteObject для его сериализации, он уважает атрибут CollectionDataContract так, как я ожидал; однако, когда я использую его как тип возврата для метода WCF, я получаю ArrayOfFoo по умолчанию.

Мне интересно, есть ли какое-то украшение, которое мне не хватает в контракте на обслуживание.

подробности:

[DataContract(Namespace = "")]
public class Foo
{
    [DataMember]
    public string BarString { get; set; }
}

[CollectionDataContract(Namespace = "")]
[Serializable]
public class FooList : List<Foo> {}

Если я просто создаю экземпляр Foo, а затем использую DataContractSerializer.WriteObject для его сериализации, я получаю то, что вы ожидаете:

<FooList>
    <Foo>
        <BarString>myString1</BarString>
    </Foo>
</FooList>

Однако, если у меня есть служба с таким методом, как этот ...

[ServiceContract Name = "MyService"]
public interface IMyService
{
    [OperationContract, WebGet(UriTemplate = "foos/")]
    FooList GetAllFoos();
}

, а затем сделать GET для http://www.someEndpoint.com/foos/, Я получаю это:

<ArrayOfFoo>
    <Foo>
        <BarString>myString1</BarString>
    </Foo>
</ArrayOfFoo>

Я также попытался указать Name = "MyFooListName" в атрибуте CollectionDataContract. Те же результаты: DataContractSerializer получает памятку; WCF нет.

Ответы [ 3 ]

3 голосов
/ 01 декабря 2010

Саид отправил меня в правильном направлении: я случайно оказался в XmlSerializer, когда я надеялся на DataContractSerializer.

Я в конечном итоге выбрал XmlSerializer ... ну ... попросив его.

В частности, я украсил методы в своем сервисе с помощью XmlSerializerFormat следующим образом:

[ServiceContract Name = "MyService"] 
public interface IMyService 
{ 
    //  ... other stuff ...

    [OperationContract, WebInvoke(UriTemplate = "foos/", Method = "POST")] 
    [XmlSerializerFormat]
    Foo PostAFoo(Foo yourNewFoo);
} 

Я сделал это в надежде простить порядок членов в свернутых вручную BLOB-объектах Foo XML.Конечно, когда это делается, получается XmlSerializer, а не DataContractSerializer.

Когда я убираю атрибут XmlSerializerFormat, проблема решается: WCF теперь сериализует мою коллекцию FooList так, как я хочу.

2 голосов
/ 01 декабря 2010

Подробнее см. MSDN :

DataContractSerializer не поддерживать модель программирования, используемую XmlSerializer и ASP.NET Web Сервисы. В частности, это не атрибуты поддержки, такие как XmlElementAttribute и XmlAttributeAttribute. Включить поддержка этой модели программирования, WCF должен быть включен для использования XmlSerializer вместо DataContractSerializer.

Таким образом, сериализация будет выполняться XMLSerializer, и вы не сможете ее изменить.

0 голосов
/ 01 декабря 2010

Вы выбрали универсальные типы при настройке службы WCF?если нет, то

щелкните правой кнопкой мыши и перейдите к настройке, затем выберите Generic Type, по умолчанию это тип массива.

...