如何通过WCF实现inheritance的Dictionary

我正在尝试实现一个用于WCF的字典。 我的要求是:

  • 实际(私有变量或基类)类型等同于Dictionary
  • Comparer = System.StringComparer.InvariantCultureIgnoreCase
  • 自定义(覆盖/新)添加(键,值)方法(包括validation)。
  • 覆盖ToString()
  • 在客户端和主机上使用相同类型

我试图在WCF主机和客户端项目共享的公共项目中使用此类:

 [Serializable] public class MyDictionary : Dictionary { public MyDictionary() : base(System.StringComparer.InvariantCultureIgnoreCase) { } public new void Add(string key, object value) { /* blah */ } public override string ToString() { /* blah */ } } [DataContract] [KnownType(typeof(MyDictionary))] [KnownType(typeof(object[]))] [KnownType(typeof(double[]))] [KnownType(typeof(string[]))] [KnownType(typeof(DateTime[]))] public class ResultClass { public object Value{ get; set; } /* More properties */ } public class ParmData { public object Value{ get; set; } /* More properties */ } [DataContract] [KnownType(typeof(MyDictionary))] [KnownType(typeof(object[]))] [KnownType(typeof(double[]))] [KnownType(typeof(string[]))] [KnownType(typeof(DateTime[]))] public class ParameterClass { public List Data{ get; set; } /* More properties */ } [OperationContract] ResultClass DoSomething(ParameterClass args); 

结果:

  • 当我将MyDictionary作为ParameterClass.Data.Value元素之一传递时,我得到一个缺少的KnownTypeexception。
  • 我可以安全地在ResultClass中返回MyDictionary,但它不再是我的类型。 它只是一个字典,不能转换为MyDictionary 。 另外comparer = System.Collections.Generic.GenericEqualityComparer ,而不是我正在寻找的不区分大小写的比较器。

我要求的帮助是要么修复我失败的尝试,要么是完全不同的方式来达到我声明的要求。 任何解决方案都不应涉及将一个字典复制到另一个

谢谢

将CollectionDataContract添加到Dictionary类:

有关使用集合数据协定实现字典的更多信息,请查看以下链接:

http://msdn.microsoft.com/en-us/library/aa347850.aspx

序言:请注意,添加“新” Add不会阻止人们通过强制转换来调用旧的Add 。 此外,就“mex”而言,这是一个非常模糊的数据合同 – 它是否需要如此开放? (很多object ……)

首先:你有没有错过那里的一些[DataContract] / [DataMember]标记? 特别是:

  • ResultClass.Value
  • ParamData
  • ParamData.Value
  • ParameterClass.Data

你能准确说明你使用的哪个版本的.NET吗? DataContractSerializer等已经通过服务包进行了调整。 安装3.5 SP1(我唯一需要处理的)它至少通过DataContractSerializer (没有WCF堆栈)进行序列化和反序列化,并调用正确的Add方法。

您能否检查以下内容是否适用于您的本地版本? (它适用于我的3.5 SP1和缺少的属性)[输出第一]:

 1 MyDictionary abc=123 def=ghi 

码:

  // or long-hand in C# 2.0 ParameterClass pc = new ParameterClass { Data = new List { new ParmData { Value = new MyDictionary { {"abc",123}, {"def","ghi"} }}}}; DataContractSerializer dcs = new DataContractSerializer(pc.GetType()); string xml; using(StringWriter sw = new StringWriter()) using(XmlWriter xw = XmlWriter.Create(sw)) { dcs.WriteObject(xw, pc); xw.Close(); xml = sw.ToString(); } using(StringReader sr = new StringReader(xml)) { ParameterClass clone = (ParameterClass)dcs.ReadObject(XmlReader.Create(sr)); Console.WriteLine(clone.Data.Count); Console.WriteLine(clone.Data[0].Value.GetType().Name); MyDictionary d = (MyDictionary)clone.Data[0].Value; foreach (KeyValuePair pair in d) { Console.WriteLine("{0}={1}", pair.Key, pair.Value); } } 

显然这只是测试DataContractSerializer (没有整个WCF堆栈),但它似乎工作……所以:相同的代码是否适用于您的本地.NET版本? 如果没有,是否安装最新的3.0 Service Pack? (理想情况下通过安装3.5 SP1)。

有关信息,我得到xml:

 abc123defghi 
  • 使用CollectionDataContract属性作为jezell建议
  • 使用/ collectionType参数使用SvcUtil手动生成引用(代理)代码。 vs2008服务引用GUI不支持此参数。

来源: WCF集合类型共享

我终于找到了办法。 我发现这个链接指向正确的方向,但我会尝试总结。

  1. 确保将[CollectionDataContract]添加到自定义集合中
  2. 像往常一样通过VS添加服务引用
  3. 展开服务引用并查找Reference.svcmap文件
  4. 在客户端选项节点下,您将看到

将其替换为以下xml。

  1. 右键单击“服务引用”,然后单击“更新”。 它不应再生成“代理”类,并允许您使用共享类。