Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do WCF and DataContractSerializer serialize CollectionDataContract-decorated collection types differently?

I have a really simple customized collection type that inherits from List<> and uses a CollectionDataContract.

When I use DataContractSerializer.WriteObject to serialize it, it respects the CollectionDataContract attribute the way I'd expect; however, when I use it as a return type for a WCF method, I get the default ArrayOfFoo.

I'm wondering if there is some decoration I'm missing in the service contract.

Details:

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

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

If I just instantiate a Foo and then use DataContractSerializer.WriteObject to serialize it, I get what you'd expect:

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

However, if I have a service with a method like this...

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

and then do a GET for http://www.someEndpoint.com/foos/, I get this:

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

I've also tried specifying Name="MyFooListName" in the CollectionDataContract attribute. Same results: DataContractSerializer gets the memo; WCF doesn't.

like image 836
pisomojado Avatar asked Nov 30 '10 19:11

pisomojado


People also ask

What is DataContractSerializer and how its different from XmlSerializer?

XmlSerializer gives more control over the generated xml structure compared to the DataContractSerializer. For ex, if a field should come as an attribute or element. 10. XmlSerializer cannot able to serialize types that implements IDictionary, for ex.

What is the type of serializer used in WCF?

Windows Communication Foundation (WCF) uses the DataContractSerializer as its default serialization engine to convert data into XML and to convert XML back into data.

What is serialization in WCF?

The process forms a sequence of bytes into a logical object; this is called an encoding process. At runtime when WCF receives the logical message, it transforms them back into corresponding . Net objects. This process is called serialization.

Which namespace is used for serialization in WCF?

DataContractSerializer as the Default By default WCF uses the DataContractSerializer class to serialize data types.


1 Answers

Saeed sent me in the right direction: I inadvertently ended up with XmlSerializer, when I had been hoping for DataContractSerializer.

I had ended up with XmlSerializer... well... by asking for it.

In particular, I had decorated methods in my service with the XmlSerializerFormat like this:

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

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

I had done this in the hopes of forgiving member order in hand-rolled Foo XML blobs. Of course, when one does this one ends up with XmlSerializer, not DataContractSerializer.

When I take away the XmlSerializerFormat attribute, problem solved: WCF is now serializing my FooList collection the way I want.

like image 193
pisomojado Avatar answered Oct 12 '22 04:10

pisomojado