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?
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.
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.
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.
[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.
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With