By default, WCF makes use of the DataContractSerializer in order to serialize and deserialize an instance of a type into an XML stream or document. Traditionally, the DataContractSerializer required the use of a supplied data contract in order to know which objects, and which members of the objects, to serialize.

I’m sure we all enjoy decorating types in common, shared assemblies (i.e. data model defining libraries) with WCF-specific attributes. I know I do.

Fortunately, the release of .NET 3.5 SP1 gave the DataContractSerializer the ability to support serializing types that aren’t decorated with these WCF contractual attributes. This is a good thing when dealing with types that originate from shared assemblies whose code we don’t wish to infect with incessant attribute placement.

Being new to WCF, I hit a brick wall due to my reliance on this new feature without being fully aware of possible complications that may arise based on the types involved. If any of you are running into the error I’m about to discuss, it is my hope that this post will save you some time.

After I finished defining and implementing a ServiceContract that made use of several complex types, I noticed the following XmlException being raised when calling the service from a client:

System.Xml.XmlException : ‘<’, hexadecimal value 0x3C, is an invalid attribute character….

The source of the exception was an XML name validation method found in an internal .NET framework class. Needless to say, if I continued execution, the service call would have ultimately failed. As a side note, this is one of the reasons why I think the release of .NET framework reference code was a very sweet move and something you should take advantage of. It especially comes in handy when dealing with new and strange technologies. If I did not have .NET framework stepping enabled, I’m sure the error that I’d have observed would have been much less fine-grained, which would have resulted in even more hair-pulling.

Upon closer inspection of the error, I eventually came to the conclusion that the exception was genuine, and that the cause for the error was indeed due to attempts to use names containing illegal characters. The following is one of the many offending names that were being used during serialization:

<Id>k__BackingField

The Id portion in the name above reflects a property in one of the types I was using, as all of the offending names did. So, what is with the ‘<>’ and ‘k__BackingField’ ?

If you’ve ever disassembled .NET assemblies, you should recognize the above name as something that is compiler generated. Indeed, this is what happens when one makes use of automatic propeties: the compiler creates a private, anonymous backing field that can only be accessed through the property’s get and set accessors. The private fields are named using the ‘<>’ syntax in order to prevent any possible conflicts with other fields defined by the developer.

Well, that’s interesting and all, but why were the compiler generated names even coming into play here? Last I heard, the DataContractSerializer handles automatic properties just fine. After much debugging, I finally came to the source of the problem: The Serializable attribute that was applied to each type.

[Serializable]
public class OffendingType : IOffendingType
{
    public int Id { get; set; }
    .
    .
    .
}

We make use of the Serializable attribute when we wish to be able to perform binary serialization on a type. It is important to remember that binary serialization does its job by the direct copying of an object’s memory image. This means that everything about the object, not just its public properties, gets copied. Because of this, the object’s private members are persisted, which includes the underlying compiler generated backing fields.

For the most part, that’s ok, but, as demonstrated by the error shown above, this will horribly screw up the serialization required for dealing with WCF clients/services. In order to resolve the issue, you need to swallow your pride and decorate the types being consumed with the appropriate WCF-specific attributes. In my case, I ended up assigning DataContract attributes to each type, as well as DataMember attributes to all the members of the type I wanted to serialize.


//All better!
[DataContract]
[Serializable]
public class OffendingType : IOffendingType
{
    [DataMember]
    public int Id { get; set; }
    .
    .
    .
}

So, the lesson learned here is: Although you should feel free to take advantage of the DataContractSerializer’s ability to serialize types that do not have the appropriate contractual attributes applied, be aware that this approach does not work when dealing with types that have the Serializable attribute applied.

Matt Weber

I'm the the Senior Software Architect at Emergingsoft where I lead the software development team. I am also the owner of this website. I enjoy well-designed code, independent thought, and the application of rationality in general. You can reach me at matt@badecho.com.

  2 Responses to “WCF Serialization: Know Your Contract”

  1. Thanks, man, for such a clear explanation of the issue. I was wondering why did my wcf client had these strange fields and how i could avoid it.

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
   
© 2012-2013 Matt Weber. All Rights Reserved. Terms of Use.