How to Return Generic Dictionary in a WebService

后端 未结 5 1587
说谎
说谎 2020-12-09 03:08

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

Dictionary GetValues(string search) {}

The

相关标签:
5条回答
  • 2020-12-09 03:30

    This article has a method to serialize IDictionaries. Look for " I've noticed that XmlSerializer won't serialize objects that implement IDictionary by default. Is there any way around this?" about 2/3 the way down the page.

    0 讨论(0)
  • 2020-12-09 03:36

    This solution with SerializableDictionary works great, but during work You can get

    cannot convert from 'SerializableDictionary<string,string>' 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, more detailed here:

    http://support.microsoft.com/kb/815131

    0 讨论(0)
  • 2020-12-09 03:37

    Create a type MyKeyValuePair<K,V>, and return a List<MyKeyValuePair<int,string>>, copied from the dictionary.

    0 讨论(0)
  • 2020-12-09 03:43

    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
    }
    
    0 讨论(0)
  • 2020-12-09 03:53

    I use this util class for serializing dictionaries, maybe it can be useful for you

    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    
    namespace Utils {
        ///<summary>
        ///</summary>
        public class SerializableDictionary : IXmlSerializable {
            private readonly IDictionary<int, string> dic;
            public DiccionarioSerializable() {
                dic = new Dictionary<int, string>();
            }
            public SerializableDictionary(IDictionary<int, string> dic) {
                this.dic = dic;
            }
            public IDictionary<int, string> Dictionary {
                get { return dic; }
            }
            public XmlSchema GetSchema() {
                return null;
            }
            public void WriteXml(XmlWriter w) {
                w.WriteStartElement("dictionary");
                foreach (int key in dic.Keys) {
                    string val = dic[key];
                    w.WriteStartElement("item");
                    w.WriteElementString("key", key.ToString());
                    w.WriteElementString("value", val);
                    w.WriteEndElement();
                }
                w.WriteEndElement();
            }
            public void ReadXml(XmlReader r) {
                if (r.Name != "dictionary") r.Read(); // move past container
                r.ReadStartElement("dictionary");
                while (r.NodeType != XmlNodeType.EndElement) {
                    r.ReadStartElement("item");
                    string key = r.ReadElementString("key");
                    string value = r.ReadElementString("value");
                    r.ReadEndElement();
                    r.MoveToContent();
                    dic.Add(Convert.ToInt32(key), value);
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题