WCF Xml序列化和自动实现的属性

时间:2009-09-26 19:46:10

标签: c# xml wcf serialization rest

我正在尝试使用WCF RESTful Web服务,而我遇到了自动实现属性的问题。

我有一个名为DeviceDescriptor的类,定义如下:

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

我有一个RESTful WCF服务,应该返回一个DeviceDescriptors列表 - 这是我的服务合同:

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

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

嗯,它有点工作,除了在XML输出中,属性名称不正确,看起来序列化程序使用自动生成的支持字段的“不可知名称”而不是属性名。我的输出如下:

<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>

那么,有没有办法解决这个问题呢?为什么没有; WCF使用属性名称?

2 个答案:

答案 0 :(得分:9)

要在评论中添加一些问题...在好的旧(3.0)天WCF / DataContractSerializer非常严格。如果您的类型未明确标记为[DataContract](或IXmlSerializable用于后备),则不会序列化。它使用标记为[DataMember]的成员,如果指定,则使用属性上的显式名称,否则使用成员名称。生活很美好。

最近,代码被更改,允许“常规”类型被序列化 - 意思是:没有数据合同的那些。它使用与BinaryFormatter使用相同的方法来执行此操作 - 即它适用于字段 -level。这是IMO不好的事:

  • 字段是实现,而不是合同
  • 如果你改变......那就太脆了!
  • 它没有多少水来防止混淆
  • 像往返于自动道具一样无辜的东西打破它(自动道具有真正奇怪的字段名称,无法在常规C#中模拟)

我知道为什么这很诱人(允许WCF传输任意类型),但我体内的每一个肌肉都说这是一个净损失。让人们使用正确的工具(数据合同)比让他们破碎的类工作更好。在原始3.0中,会有一个异常抛出告诉您如何正确解决此问题:将其标记为[DataContract]并告诉它您要序列化哪个[DataMember]

另请参阅:Obfuscation, serialization and automatically implemented properties

答案 1 :(得分:4)

它使用反射来获取它们IIRC,如果你想要更多的控制,你应该尝试使用DataContract,它允许你指定确切的名称(使用[DataMember(Name = "DeviceID")])。另请参阅DataMemberAttribute

上的文档