WCF Data Contracts and "k__BackingField" Property Naming

So recently, I was playing around with WCF, and I created a few classes that I wanted to expose in operations. Usually when I play with plain old objects, I tend to type them up pretty lazily and use any code shortcut I can. In this case I defined my properties using the 3.0 auto-generated field method, which looks like an interface property. The C# compiler automatically generates the backing field on the fly for me at compile time.  Here is a sample class I'm using in the silverlight music project.

[Serializable]  
public class FileBrowser  
{
    public string LocalMusicRoot { get; set; }
    public string WebMusicRoot { get; set; }
    public List<string> Files { get; set; }
}

imageThe catch comes in when you expose it to WCF. When serializing these objects, the serializer will look at all FIELDS of the class no matter their scope:  public, private, etc.  This is because it uses System.Runtime.Serialization, not System.Xml.Serialization. It does not serialize properties since properties really are just accessor functions.  So what you get is a funky looking proxy class with some properties you didn't want and some cryptic naming. I.E. k__BackingField appended to your field names. The serializer simply takes what it has which is the auto-generated field name the C# compiler made for us.

So how do I clean this up?!?!   Easy!  Use a data contract.   By defining your classes using the DataContract attribute from System.Runtime.Serialization, the serializer will interpret your DataMembers as fields on the class and use your naming. It will also ignore anything that's not defined as a DataMember; so that hidden stuff will remain hidden and not be included in the proxy class. Take a look at this.  We modified our original class with these attributes and the generated proxy class on the right now uses the names and fields we want!  Easy peasy!

[DataContract]  
public class FileBrowser  
{
    [DataMember]
    public string LocalMusicRoot { get; set; }

    [DataMember]
    public string WebMusicRoot { get; set; }

    [DataMember]
    public List<string> Files { get; set; }
}

imageSo now...  When you're defining your entity classes that you want to pass around WCF; just be sure to take advantage of DataContract attributes to clean up the client proxy classes.

By the way... If you're playing around with SubSonic 3 Alpha, this is a really sweet tweak you can make to your classes.tt T4 template.  This will make them all Data Contracts and put DataMember attributes on each of the data fields. This will hide the foreign key properties from the WCF generated proxies.  Good stuff! :)

comments powered by Disqus