C# 如何使WCF序列化在通用字典上保留非默认比较器?
假设我们在VisualStudio2010中从头开始,添加一个“WCF服务应用程序”。我们添加了此方法和实现:C# 如何使WCF序列化在通用字典上保留非默认比较器?,c#,wcf,serialization,dictionary,iequalitycomparer,C#,Wcf,Serialization,Dictionary,Iequalitycomparer,假设我们在VisualStudio2010中从头开始,添加一个“WCF服务应用程序”。我们添加了此方法和实现: // (in IService1.cs) [OperationContract] Dictionary<string, string> GetDictionary(); // (in Service1.svc.cs) public Dictionary<string, string> GetDictionary() {
// (in IService1.cs)
[OperationContract]
Dictionary<string, string> GetDictionary();
// (in Service1.svc.cs)
public Dictionary<string, string> GetDictionary()
{
return new Dictionary<string, string>(
StringComparer.InvariantCultureIgnoreCase);
}
我们预计这段代码会失效,因为不区分大小写的字典会将key
和key
视为同一个键,因此会抛出第二个Add
不幸的是,当所有东西都被编译和运行时,我们会看到一张悲伤的脸:(),因为当字典
遇到WCF层时,它“忘记”它是用一个特定的、非默认的比较器
生成的,而是获取字符串
的默认相等比较器
是否有一个易于更改的设置,以便字典
的比较器
属性在传输过程中得到保留?还是我必须创建一个自定义类?
(我看到了,但没有给我多少启示。我也看到了,但这是我的问题,不是答案)如果使用“添加服务引用”之类的标准机制等等,WCF按设计将根据连线上的结构创建一个完全独立的数据结构副本,例如,可以用XML模式(XSD)表示的XML序列化结构 这不包括任何行为(代码)而不是实际数据的东西,比如比较器等
没有设置“开启”此功能-这是无法做到的。解决此问题的唯一方法-当您控制通信线路的两端,并且两者都是.NET平台时-是共享双方都需要的常见内容(服务合同、数据合同等)在服务器和客户机都引用的单独程序集中。在客户机上,您需要确保在创建WCF代理之前将引用添加到该共享程序集中-在这种情况下,WCF运行时将重用现有数据结构(如带有自定义比较器的字典)从共享组件,而不是创建新的锅炉板副本。太好了!我在让我赚大钱的那块上加了一点亮点:)
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();