Custom SOAP XML Namespace Serialization for Array Items in a WCF DataContract

April 25, 2012 at 4:52 pm (Programming/Development)

Just thought I’d share this little tidbit of gold that I found after working on this issue for a few hours today:

WCF is a big step forward in .NET SOA development and I’ve really enjoyed working with it over the past several months after working with .NET 2.x ASMX based services previously. However, I ran into an issue where the items in an array which is part of a request’s DataContract were being serialized into a separate namespace from the array object itself. Here’s an example to see what I mean:

In our DataContract:

  [DataContract(
    Name = "MyCoolDataContract",
    Namespace = "http://blah.com/DataContracts")]
  public class MyCoolDataContract
  {
    [DataMember(
      Name = "MyArrayOfGuids")]
    public Guid[] MyArrayOfGuids { get; set; }
...stuff...

The resulting SOAP request generated from the WSDL:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dat="http://blah.com/DataContracts"
xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
... stuff...
            <dat:MyArrayOfGuids>
               <!--Zero or more repetitions:-->
               <arr:guid>247b37ec-b59d-40e9-a7e7-b531cb042e64</arr:guid>
            </dat:MyArrayOfGuids>

Notice that the namespace for MyArrayOfGuids is dat but the namespace for the Guids it contains is arr.
This arr namespace is mapped to http://schemas.microsoft.com/2003/10/Serialization/Arrays. According to my Googling, this is the namespace under which Microsoft serializes items within any type of Array or similar collection (Lists, etc.) in a WCF DataContract.

This behavior was giving a web engineer who was attempting to call into my service some headaches when attempting to build an appropriate SOAP request.

So, after attempting many different things to get the items to serialize under the same namespace as the array object itself, I came across a pretty simple solution which has worked nicely. (ref. http://social.msdn.microsoft.com/Forums/eu/wcf/thread/9343e440-751c-48ce-b56b-83c099abcd58)

Create your own class to “wrap” the collection and serialize it under the proper namespace:

[CollectionDataContract(
ItemName = "Guid",
Namespace = "http://blah.com/DataContracts")]
public class ArrayOfGuid : List<Guid> { }

After creating that class just change the data type of the collection in your original DataContract to the custom class:

public Guid[] MyArrayOfGuids { get; set; }

becomes

public ArrayOfGuid MyArrayOfGuids { get; set; }

Now you’ll be serialized in your own terms… Down with the man!

Permalink 1 Comment