Передача объекта IDictionary в веб-сервис
В моем файле ASMX у меня есть
[WebMethod]
[ScriptMethod]
public void Method(IDictionary<string, CustomClass> objectOfCustomClass)
{
//do stuff
}
Пользовательский класс определяется как:
public class CustomClass
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Все идет хорошо, и веб-сервис успешно используется методом Ajax Jquery. Недавно я решил протестировать и попробовать получить к нему доступ по прямому URL-адресу, например http://localhost/Services.asmx/Method
и я получаю это сообщение
"Не удалось сериализовать интерфейс System.Collections.Generic.IDictionary"
Это кажется выключенным. Что вызывает это и это нормально? Я сбит с толку - кажется, что это чистый способ сделать что-то, но, по мнению Microsoft, этого делать не следует, но он работает, только не при непосредственном доступе к веб-сервису. Что дает? Я также читал на некоторых сайтах MS, что вы не можете передать IDictionary веб-сервису в качестве параметра, но он работает нормально... ТАК это можно сделать или нет? Может ли кто-то уточнить это раз и навсегда?
2 ответа
К сожалению, да, это нормально. То, что вы видите, является ограничением сериализации XML (XmlSerializer) в классическом стеке веб-служб ASP.NET - он отказывается работать со всем, что реализует IDictionary.
Служба, доступная для JavaScript через [ScriptMethod], использует другой сериализатор (JavaScriptSerializer), который не имеет этого ограничения.
Когда вы вызываете сервис из JavaScript, вы вызываете конечную точку JSON (объявлена с помощью [ScriptMethod]). Однако, когда вы тестируете из браузера, вы достигаете традиционной точки XML (объявленной с помощью [WebMethod]).
Есть некоторые обходные пути, см., Например, этот вопрос. Однако если вам требуется только поддержка клиентов AJAX, вы можете просто удалить конечную точку XML (атрибут [WebMethod]) и избежать этой проблемы.
Как примечание, улучшенный сериализатор в WCF поддерживает сериализацию словарей.
Веб-сервисы ASMX сериализуют и десериализуют объекты с использованием XmlSerializer, и не существует хорошего способа представления словаря в правильной XML-схеме. К сожалению, я не думаю, что есть хороший способ обойти это, кроме преобразования вашего IDictionary в другой тип объекта, который может быть сериализован XmlSerializer.
Взято из этой статьи "Сериализация XML в.NET Framework" ( http://msdn.microsoft.com/en-us/library/ms950721.aspx):
В: Почему я не могу сериализовать хеш-таблицы?
A: XmlSerializer не может обрабатывать классы, реализующие интерфейс IDictionary. Это было отчасти связано с ограничениями графика и отчасти из-за того, что хэш-таблица не имеет аналога в системе типов XSD. Единственное решение - реализовать собственную хеш-таблицу, которая не реализует интерфейс IDictionary.
Я обнаружил ту же проблему, просто изменил тип IDictionary на динамический.
Все остальное работает так же.