我正在尝试使用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使用属性名称?
答案 0 :(得分:9)
要在评论中添加一些问题...在好的旧(3.0)天WCF / DataContractSerializer
非常严格。如果您的类型未明确标记为[DataContract]
(或IXmlSerializable
用于后备),则不会序列化。它使用标记为[DataMember]
的成员,如果指定,则使用属性上的显式名称,否则使用成员名称。生活很美好。
最近,代码被更改,允许“常规”类型被序列化 - 意思是:没有数据合同的那些。它使用与BinaryFormatter
使用相同的方法来执行此操作 - 即它适用于字段 -level。这是IMO不好的事:
我知道为什么这很诱人(允许WCF传输任意类型),但我体内的每一个肌肉都说这是一个净损失。让人们使用正确的工具(数据合同)比让他们破碎的类工作更好。在原始3.0中,会有一个异常抛出告诉您如何正确解决此问题:将其标记为[DataContract]
并告诉它您要序列化哪个[DataMember]
另请参阅:Obfuscation, serialization and automatically implemented properties
答案 1 :(得分:4)
它使用反射来获取它们IIRC,如果你想要更多的控制,你应该尝试使用DataContract,它允许你指定确切的名称(使用[DataMember(Name = "DeviceID")]
)。另请参阅DataMemberAttribute