如何获得WCF序列化以保留泛型字典上的非默认Comparer?

时间:2011-11-15 17:33:08

标签: c# wcf serialization dictionary iequalitycomparer

假设我们从头开始在Visual Studio 2010中添加“WCF服务应用程序”。我们添加了这个方法和实现:

// (in IService1.cs)
    [OperationContract]
    Dictionary<string, string> GetDictionary();

// (in Service1.svc.cs)
    public Dictionary<string, string> GetDictionary()
    {
        return new Dictionary<string, string>(
            StringComparer.InvariantCultureIgnoreCase);
    }

然后我们将新的“控制台应用程序”添加到同一解决方案中,向我们的服务项目添加服务引用(使用所有默认设置),并将此代码添加到Main

        var c = new ServiceReference1.Service1Client();

        var d = c.GetDictionary();

        d.Add("key",string.Empty);
        // Since this *should* be a case-insensitive dictionary,
        // this add *should* fail
        d.Add("KEY", string.Empty);

        Console.WriteLine("Both Add()s succeeded :(");
        Console.ReadKey();

我们希望此代码能够翻身,因为不区分大小写的字典会将keyKEY视为相同的密钥,因此会抛出第二个Add

不幸的是,当所有内容都被编译并运行时,我们会感到悲伤:(,因为当Dictionary遇到WCF层时,它会'忘记'它是用特定的,非默认值为Comparer,而是获取string的默认相等比较器。

是否有一个简单的设置可以更改,以便Comparer的{​​{1}}属性在线路上保留?或者我必须创建自定义类吗?

(我见过XML serialization of a Dictionary with a custom IEqualityComparer但它并没有给我很多启示。我也见过this codeproject comment from 3 years ago,但这是我的问题,而不是答案)

1 个答案:

答案 0 :(得分:6)

如果您使用“添加服务参考”等标准机制,WCF 按设计将基于副本数据结构电线上的结构 ,例如XML序列化的 结构 ,可以用XML模式(XSD)表示。

包含更多行为(代码)而非实际数据的内容 - 比较器等内容。

没有设置“开启”此功能 - 它无法完成。解决这个问题的唯一方法 - 当您控制通信线路的两端,并且都是.NET平台时 - 是共享双方都需要的常见内容(服务合同,数据合同等)服务器以及客户端引用的单独程序集。在客户端上,您需要确保在创建WCF代理之前添加对该共享程序集的引用 - 在这种情况下,WCF运行时将重用现有的数据结构(例如您的字典与自定义comparer)来自共享程序集,而不是创建新的样板文件。