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

Aak*_*shM 2 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);
    }
Run Code Online (Sandbox Code Playgroud)

然后我们将新的"控制台应用程序"添加到同一解决方案中,向我们的服务项目添加服务引用(使用所有默认设置),并将此代码添加到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();
Run Code Online (Sandbox Code Playgroud)

我们希望这个代码摔倒,因为不区分大小写的字典会认为keyKEY为相同的密钥,因此将引发第二Add.

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

是否有一个简单的设置可以改变,以便在穿过电线时保留它的Comparer属性Dictionary?或者我必须创建一个自定义类?

(我已经看到了带有自定义IEqualityComparer的字典的XML序列化,但它没有给我很多启示.我也看过3年前的这个代码项目评论,但这是我的问题,而不是答案)

mar*_*c_s 6

如果您使用标准的机制,如"添加服务引用"等,WCF 通过设计将创造一个完全独立的副本基础上,你的数据结构的结构在电线上,例如XML序列化的结构,可以在XML架构来表示( XSD).

这并没有包括任何更行为(代码),而不是实际的数据-比如comparers等.

没有设置"打开"它 - 它只是无法完成.解决这个问题的唯一方法 - 当你控制通信线的两端,并且都是.NET平台时 - 是在一个单独的程序集中共享双方都需要的常见内容(服务合同,数据合同等)以及客户参考.在客户端上,您需要确保创建WCF代理之前添加对该共享程序集的引用- 在这种情况下,WCF运行时将重用共享程序集中的现有数据结构(如带有自定义比较器的字典),而不是创建新的锅炉板副本.