Подтвердить что ты не робот

Как вернуть общий словарь в WebService

Мне нужна веб-служба на С#, которая возвращает словарь, в соответствии с поиском:

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

Однако веб-служба компилируется, когда я пытаюсь ссылаться на нее, я получаю следующую ошибку: "не поддерживается, потому что он реализует IDictionary."

¿Что я могу сделать, чтобы заставить это работать?, любые идеи, не связанные с возвратом DataTable?

4b9b3361

Ответ 2

Нет "дефолтного" способа взять словарь и превратить его в XML. Вы должны выбрать способ, и клиенты вашего веб-сервиса должны будут знать об этом, когда они используют ваш сервис. Если оба клиента и сервер являются .NET, то вы можете просто использовать один и тот же код для сериализации и десериализации словарей в XML на обоих концах.

В этом блоге есть код, чтобы сделать это . Этот код использует сериализацию по умолчанию для ключей и значений словаря, что полезно, когда у вас есть нестроковые типы для обоих. Код использует наследование для выполнения своей задачи (вы должны использовать этот подкласс для хранения ваших значений). Вы также можете использовать подход типа "оболочка", как это сделано в последнем элементе в в этой статье, но обратите внимание, что в коде в этой статье используется только ToString, поэтому вы должны объединить его с первой статьей.

Поскольку я согласен с Джоэлем в том, что StackOverflow является каноническим источником для всего, ниже приведена копия кода из первой ссылки. Если вы заметили какие-либо ошибки, отредактируйте этот ответ!

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
}

Ответ 3

Создайте тип MyKeyValuePair<K,V> и верните List<MyKeyValuePair<int,string>>, скопированный из словаря.

Ответ 4

Я использую этот класс util для сериализации словарей, возможно, он может быть вам полезен

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);
            }
        }
    }
}

Ответ 5

Это решение с SerializableDictionary отлично работает, но во время работы вы можете получить

cannot convert from 'SerializableDictionary<string,string>' to 'System.Data.DataSet'

ошибка. В этом случае вам следует перейти Project- > Показать все файлы, а затем отредактировать тип аргумента SerializableDictionary в файле Reference.cs веб-службы. Это официальная ошибка Microsoft, более подробная информация здесь:

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