Как передать словарь в веб-сервис

#.net #web-services #asmx

#.net #веб-сервисы #asmx

Вопрос:

Я создал простой сервис для предоставления параметров конфигурации в виде словаря. Я создал новый SerializableDictionary класс, который реализует IXmlSerializable, как описано на этой плате. Когда я добавляю сервис (через «Добавить ссылку на сервис» в моем потребительском проекте), сигнатура метода показывает, что он возвращает набор данных. Когда я проверяю набор данных во время выполнения, он пуст.

Вот мой сервис:

 [WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
public class AppSettingsService : System.Web.Services.WebService
{
        [WebMethod]
        public SerializableDictionary<string, string> ReadAppSettings()
        {
            return AppSettings.Settings; // Settings is a SerializableDictionary<string, string>
        }
}
  

На стороне клиента я делаю это:

 using Clients.AppSettingsServiceReference;

        static AppSettings()
        {
            AppSettingsServiceSoapClient client = new AppSettingsServiceSoapClient();
            var settings = client.ReadAppSettings();
            // ...
        }
  

Я ожидаю, что settings будут SerializableDictionary, но это пустой набор данных. Я пытался отправить его в виде списка пар значений ключей, как предложено здесь и в других местах, но это также возвращает DataSet. Я использую C #, ASP.Net 3.5, VS2008 Pro
Я уверен, что упускаю из виду что-то простое, но я не могу это найти. Может кто-нибудь показать мне, как это сделать?

Ответ №1:

Как правило, веб-сервисы любого типа не понимают типы данных, специфичные для платформы, на которой вы работаете.

В частности, нет общего понятия «словарь», поэтому веб-службы их не понимают.

Более того, нет способа получить что-либо похожее на словарь через веб-службы ASMX. Если бы вы использовали WCF (как вы должны делать для всех новых разработок), тогда вы могли бы использовать те же типы на клиенте, что и на службе.

Конечно, у вас все равно была бы та же проблема, если бы ваш клиент и служба не были запущены одновременно .NET.

Ответ №2:

Джон Сондерс прав: на самом деле это невозможно. «Правильный» способ сделать то, что вы пытаетесь сделать, — это создать класс, представляющий пары ключ-значение, которые вы действительно пытаетесь вернуть, а затем вернуть IEnumerable этого класса. Например:

 public class AppSetting
{
    public string Name {get;set;}
    public string Value {get;set;}
}

    [WebMethod]
    public IEnumerable<AppSetting> ReadAppSettings()
    {
        return AppSettings.Settings.Select(
            kvp => new AppSetting{Name = kvp.Key, Value = kvp.Value});
    }
  

Это предоставляет данные непосредственно потребителю: пусть они решают, хотят ли они представить это в виде словаря / хэш-таблицы, списка, массива, дерева или любой другой структуры данных, которую они решат создать из этого. Все, о чем вы заботитесь с точки зрения целостности данных, — это убедиться, что каждый ключ привязан к правильному значению.