Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Return Generic Dictionary in a WebService

Tags:

c#

generics

I want a Web Service in C# that returns a Dictionary, according to a search:

Dictionary<int, string> GetValues(string search) {} 

The Web Service compiles fine, however, when i try to reference it, i get the following error: "is not supported because it implements IDictionary."

¿What can I do in order to get this working?, any ideas not involving return a DataTable?

like image 717
Jhonny D. Cano -Leftware- Avatar asked Mar 24 '09 20:03

Jhonny D. Cano -Leftware-


1 Answers

There's no "default" way to take a Dictionary and turn it into XML. You have to pick a way, and your web service's clients will have to be aware of that same way when they are using your service. If both client and server are .NET, then you can simply use the same code to serialize and deserialize Dictionaries to XML on both ends.

There's code to do this in this blog post. This code uses the default serialization for the keys and values of the Dictionary, which is useful when you have non-string types for either. The code uses inheritance to do its thing (you have to use that subclass to store your values). You could also use a wrapper-type approach as done in the last item in this article, but note that the code in that article just uses ToString, so you should combine it with the first article.

Because I agree with Joel about StackOverflow being the canonical source for everything, below is a copy of the code from the first link. If you notice any bugs, edit this answer!

using System; using System.Collections.Generic; using System.Text; using System.Xml.Serialization;  [XmlRoot("dictionary")] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable {     #region IXmlSerializable Members      public System.Xml.Schema.XmlSchema GetSchema()     {         return null;     }      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();     }      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 } 
like image 87
Warren Blanchet Avatar answered Oct 10 '22 09:10

Warren Blanchet