Skip to content

[C#] .net WebService返回 Dictionary 时序列化问题

今天在实现一个WebService方法时想放回一个Dictionary,编译通过,但是运行时报“is not supported because it implements IDictionary.”,这时由于Dictionary不能进行xml序列化引起的,因此我们要实现一个继承IXmlSerializable序列化接口的类才可以,代码如下:

  [XmlRoot("SerializableDictionary")]
  public class SerializableDictionary
    : Dictionary, IXmlSerializable
  {
    #region 构造函数
    public SerializableDictionary()
      : base()
    {
    }
    public SerializableDictionary(IDictionary dictionary)
      : base(dictionary)
    {
    }
    #endregion
    #region IXmlSerializable Members
    public System.Xml.Schema.XmlSchema GetSchema()
    {
      return null;
    }
    /// 
    /// 从对象的 XML 表示形式生成该对象
    /// 
    /// 
    public void ReadXml(System.Xml.XmlReader reader)
    {
      XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
      XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
      bool wasEmpty = reader.IsEmptyElement;
      reader.Read();
      if (wasEmpty)
        return;
      while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
      {
        reader.ReadStartElement("item");
        reader.ReadStartElement("key");
        TKey key = (TKey)keySerializer.Deserialize(reader);
        reader.ReadEndElement();
        reader.ReadStartElement("value");
        TValue value = (TValue)valueSerializer.Deserialize(reader);
        reader.ReadEndElement();
        this.Add(key, value);
        reader.ReadEndElement();
        reader.MoveToContent();
      }
      reader.ReadEndElement();
    }

    /**/
    /// 
    /// 将对象转换为其 XML 表示形式
    /// 
    /// 
    public void WriteXml(System.Xml.XmlWriter writer)
    {
      XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
      XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
      foreach (TKey key in this.Keys)
      {
        writer.WriteStartElement("item");
        writer.WriteStartElement("key");
        keySerializer.Serialize(writer, key);
        writer.WriteEndElement();
        writer.WriteStartElement("value");
        TValue value = this[key];
        valueSerializer.Serialize(writer, value);
        writer.WriteEndElement();
        writer.WriteEndElement();
      }
    }
    #endregion
  }

然后在要返回Dictionary的方法里使用SerializableDictionary构造方法,像这样:

public SerializableDictionary Func()
{
    Dictionary a = new Dictionary();
    a.Add(1,"a");
    a.Add(2,"b");
    a.Add(3,"c");
    return new SerializableDictionary(a);
}

以为这样就大功告成了,但是在客户端引用的时候又出现了问题,看了一下Func()的返回结果居然是DataSet,然后费了好大的功夫想把DataSet转化一下,发现根本转不过来,于是又求助了万能的谷歌,在 栈溢出了 上面找到了下面的方法:
[amazon_link asins=’B01LW72R2M,B00P8VZ8T4,B015316YQE’ template=’CopyOf-ProductGrid’ store=’boyd-23′ marketplace=’CN’ link_id=”]

This solution with SerializableDictionary works great, but during work You can get cannot convert from 'SerializableDictionary' to 'System.Data.DataSet' error. 
In this case You should go Project-> Show all files, and then edit argument type to SerializableDictionary in Reference.cs file of web service. It's an official microsoft bug

上面说明了这是一个微软官方的bug,需要手动把Reference.cs里面方法的返回类型DataSet手动修改成自定义的类型,例如:
原代码

        public System.Data.DataSet Func() {
            object[] results = this.Invoke("Func", new object[0]);
            return ((System.Data.DataSet)(results[0]));
        }

把上面代码中的两处System.Data.DataSet改成Dictionary就大功告成了,像这样:

        public Dictionary Func() {
            object[] results = this.Invoke("Func", new object[0]);
            return ((Dictionary)(results[0]));
        }

参考连接:
http://social.msdn.microsoft.com/Forums/vstudio/zh-CN/110fc8c1-99a2-4bc5-a1ac-1bee2fd3a922/dictionaryintstring?forum=visualcshartzhchs
http://support.microsoft.com/kb/815131#top

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x