Передача объекта 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 на динамический.

Все остальное работает так же.

Другие вопросы по тегам