c# - 如何进行 WCF 序列化以在通用字典上保留非默认比较器?

标签 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 视为相同的键,因此会抛出第二个 添加

不幸的是,当所有内容都编译并运行时,我们会得到一张悲伤的脸:(,因为当Dictionary遇到WCF层时,它“忘记”了它是使用特定的非默认 Comparer 进行创建,并获取 string 的默认相等比较器。

是否有一个简单的设置可以更改,以便在通过网络时保留 DictionaryComparer 属性?或者我必须创建一个自定义类?

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

最佳答案

如果您使用“添加服务引用”等标准机制,WCF 设计将基于创建数据结构的完全独立的副本>电线上的结构,例如可以用 XML 架构 (XSD) 表示的 XML 序列化结构

包括任何更多行为(代码)而不是实际数据的内容 - 例如比较器等。

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

关于c# - 如何进行 WCF 序列化以在通用字典上保留非默认比较器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8140583/

相关文章:

c# - 带参数的任务列表

C# - 如何修改 getter 给出的结构?

ajax - 为什么使用 wsHttpBinding 时 InstanceContextMode.PerSession 的行为类似于 PerCall?

c# - 如何撤销 WCF 中的客户端证书?

c# - 服务 - 客户端界面、架构建议

c# - C# 可移植类库中用于序列化的代理类型

c# - 如何将自定义功能区导入 Excel

c# - 在 .NET 中使用 wsdl 创建对象

c# - WCF:从多行返回单行

linq - 是否可以序列化分组列表?