在wcf上使用通用词典:我需要查找什么?

时间:2009-08-20 02:27:01

标签: .net wcf generics dictionary

假设我在合同中有一个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 articlethis blog post,现在我很困惑,如果我必须了解很多关于DataContractSerializer以及服务如何序列化Photos属性的细节。

我是否需要去那里,或者我能做些什么让服务器上的WCF自动与我的客户端交互?在我看来,所有的序列化细节应该能够被抽象出来 - 我只想在消费客户端应用程序中结束:

Dim foo as Thing = ThingServiceClient.GetThing(someGuid)
Dim myPhotos as Dictionary(Of String, Photo) = foo.Photos

在我的定义中,我需要做些什么来使这项工作?我需要在其他地方做些什么才能让它发挥作用?我是否需要担心确保服务坚持使用DataContractSerializer并且不会回退使用XmlSerializer?

3 个答案:

答案 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运行时为您处理。

马克