假设我在合同中有一个WCF服务和一个方法
<ServiceContract()> _
Interface IThingService
'...
<OperationContract()> _
Function GetThing(thingId As Guid) As Thing
End Interface
其中Thing是具有普通属性的普通类,除了一个成员:
Public Class Thing
' ...
Public Property Photos() As Dictionary(Of String, Photo)
' ...
End Class
其中Photo是具有普通属性的普通类。
所以我深入研究了一些文档,例如this MSDN article和this blog post,现在我很困惑,如果我必须了解很多关于DataContractSerializer以及服务如何序列化Photos属性的细节。
我是否需要去那里,或者我能做些什么让服务器上的WCF自动与我的客户端交互?在我看来,所有的序列化细节应该能够被抽象出来 - 我只想在消费客户端应用程序中结束:
Dim foo as Thing = ThingServiceClient.GetThing(someGuid)
Dim myPhotos as Dictionary(Of String, Photo) = foo.Photos
在我的定义中,我需要做些什么来使这项工作?我需要在其他地方做些什么才能让它发挥作用?我是否需要担心确保服务坚持使用DataContractSerializer并且不会回退使用XmlSerializer?
答案 0 :(得分:3)
我差点自杀试图解决这个问题。最后,我还活着,并且有一个很好的代码。享受它:))
[DataContract, Serializable]
[KnownType("GetKnownTypes")]
public class Dto
{
[DataMember]
public Int PropertyA { get; set; }
[DataMember]
public String PropertyB { get; set; }
[DataMember]
public Dictionary<string, object> MyDictionary { get; set; }
private static Type[] GetKnownTypes()
{
return _myDictionaryValueTypes ?? new Type[] { Typeof(Dictionary<string, object>) };
}
private void MyDictionaryValueTypes()
{
if (XmlDictionary == null) return;
_myDictionaryValueTypes = XmlDictionary.Values.Where(value => value != null).Select(value => value.GetType()).ToArray();
}
}
您唯一需要确保的是调用MyDictionaryValueTypes,就是这样。
答案 1 :(得分:1)
我会小心将业务对象直接暴露在WCF合同(或asmx Web服务或任何其他外部入口点进入系统)中。这是外部系统使用的接口,即使您的业务对象在内部发生更改,此类接口也应保持不变。业务对象上还可以有一些在服务器上有意义的功能,但在客户端上却没有。
此外,您突然需要修改您的业务对象,以使其适合您选择的通信技术,例如:你必须在你的业务类上放置属性,这些属性与业务类没有任何关系。
我会创建一个ThingDTO(DTO =数据传输对象),其中包含要传输到客户端的数据,并使用Thing实例中的数据对其进行初始化。这意味着如果您认为WCF服务是系统的外观,那么ThingDTO就是外观层的一部分。因此,控制WCF序列化的属性可以在这里自由进行。
那就是说,它与你的情况有意义不一样。这只是我从WCF接口返回业务类的一般看法。
答案 2 :(得分:0)
您需要确保使用[DataContract]
属性修饰“Thing”,并且要包含在数据协定中的所有成员必须具有[DataMember]
属性。你的“照片”课也一样。
只要您不必处理多态(继承)和/或自定义集合,那就应该是真的。其余部分应由WCF运行时为您处理。
马克