Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Xml Serialization and AutoImplemented Properties

I'm experimenting with WCF RESTful web services and I'm having a problem with Auto-Implemented properties.

I have a class called DeviceDescriptor, defined as follows:

public class DeviceDescriptor
{
    public string DeviceId { get; set; }
    public string DisplayName { get; set; }
}

I have a RESTful WCF service that is supposed to return a List of DeviceDescriptors - here's my service contract:

[ServiceContract]
public interface IChooser
{
[WebGet(UriTemplate="/Chooser/RegisteredDevices")]
[OperationContract]
List<DeviceDescriptor> RegisteredDevices();

[WebGet(UriTemplate = "/Chooser/Ping")]
[OperationContract]
string Ping();
}

Well, it sort of works, except that in the XML output, the property names don't come out right, it looks like the serializer is using the "unutterable names" of the auto-generated backing fields instead of the property names. My output comes out like this:

<DeviceDescriptor>
  <_x003C_DeviceId_x003E_k__BackingField>Pipe.Dome</_x003C_DeviceId_x003E_k__BackingField> 
  <_x003C_DisplayName_x003E_k__BackingField>Pipe diagnostic tool</_x003C_DisplayName_x003E_k__BackingField> 
</DeviceDescriptor>

So, is there a way out of this? Why doesn;t WCF use the property names?

like image 619
Tim Long Avatar asked Sep 26 '09 19:09

Tim Long


People also ask

Does WCF use XML?

Windows Communication Foundation (WCF) can use two different serialization technologies to turn the data in your application into XML that is transmitted between clients and services, a process called serialization.

What is serialization 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. The DataContractSerializer is designed to serialize data contract types.

What is serialization and Deserialization in WCF?

For an introduction to data contracts, see Using Data Contracts. When deserializing XML, the serializer uses the XmlReader and XmlWriter classes. It also supports the XmlDictionaryReader and XmlDictionaryWriter classes to enable it to produce optimized XML in some cases, such as when using the WCF binary XML format.

What is DataContract attribute?

[DataContract] attribute specifies the data, which is to serialize (in short conversion of structured data into some format like Binary, XML etc.) and deserialize(opposite of serialization) in order to exchange between the client and the Service.


1 Answers

To add some detail to the question you ask in the comments... in the good old (3.0) days WCF/DataContractSerializer was pretty strict. If your type wasn't explicitly marked as a [DataContract] (or IXmlSerializable for fallback) then it wouldn't serialize. It used the members marked as [DataMember], using the explicit name on the attribute if specified, or the member-name otherwise. Life was good.

More recently, the code was changed allowing "regular" types to be serialized - meaning: those without data-contracts. It does this using the same approach as BinaryFormatter uses - i.e. it works at the field-level. This is IMO bad:

  • fields are the implementation, not the contract
  • it is brittle if you change... anything!
  • it doesn't hold much water against obfuscation
  • something as innocent as switch to/from an auto-prop break it (auto-props have truly bizarre field names, that can't be emulated in regular C#)

I know why this was tempting (to allow WCF to transport arbitrary types), but every sinew in my body says this was a net loss. It is much better to make people use the right tools (data-contracts) than it is to let their broken classes work. In the original 3.0, there would have been an exception thrown telling you how to fix this correctly: mark it as a [DataContract] and tell it which [DataMember]s you want to serialize.

See also: Obfuscation, serialization and automatically implemented properties

like image 90
Marc Gravell Avatar answered Sep 17 '22 21:09

Marc Gravell