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.

 

The company I work for provides resource scheduling solutions, mainly in the form of web and database server software coupled with an Outlook addin client. It is a complex addin that gets deployed to thousands of users in large corporate environments, and it is something I spend a sizeable amount of my time working on.

It is entirely written in old school COM, and has quite a history. Due to various reasons, there has been a strong pull to rewrite the software using newer technologies (.NET). I have recently begun the design and implementation of the new addin, and one of the first things I stopped to take a look at was VSTO.

The motivation for making the technological move lies completely with the ability to use .NET, among other issues with the current incarnation’s design. The ability to use VSTO was not the basis for the move; however, we would have gladly used it if the benefits were high.

I found VSTO to be incredibly disappointing due to a single, yet extremely powerful, reason. This single reason actually has caused me to question Microsoft’s view on addin development in general. Read on for my analysis of VSTO’s crippling fault, and why it makes the platform almost useless (at least for any serious addin development). I will also offer (what I view as) the correct course of action to take in regards to the serious problems caused by this crippling fault.

Continue reading »

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