#.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});
}
Это предоставляет данные непосредственно потребителю: пусть они решают, хотят ли они представить это в виде словаря / хэш-таблицы, списка, массива, дерева или любой другой структуры данных, которую они решат создать из этого. Все, о чем вы заботитесь с точки зрения целостности данных, — это убедиться, что каждый ключ привязан к правильному значению.