отправка запроса с общим типом данных из FlashBuilder4 в службу wcf

#wcf #apache-flex #object #soap #flash-builder

#wcf #apache-flex #объект #soap #flash-builder

Вопрос:

На сервере настроена служба wcf, которая поставляет данные в проект flex, созданный с использованием Flashbuilder4. Я использовал функцию самоанализа веб-сервиса для генерации DTO и служебных прокси. Один из DTO имеет свойство типа Object. Содержимое этого универсального объекта будет меняться в зависимости от определенных условий, но всегда будет другим сложным объектом. Создание и заполнение vo в FB4 проходит гладко, но когда объект сериализуется, он выглядит следующим образом:

 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<SOAP-ENV:Body> 
<tns:GetC xmlns:tns="EP2ProblemDemo1"> 
<tns:anyObj> 
<tns:Property1>yo!</tns:Property1> 
<tns:Property2>yo! yo!</tns:Property2> 
</tns:anyObj> 
</tns:GetC> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope>
  

Где вы можете заметить, что в свойстве anyObj отсутствует какая-либо информация о типе, несмотря на ссылку на объект типа ClassB:

 public class ClassA
{
    public string Property1;
}
public class ClassB : ClassA
{
    public string Property2;
}
  

В аргументе anyObj для GetC отсутствует что-то вроде следующего:

xsi:type=»tns:ClassB» xmlns:tns=»EP2ProblemDemo1″

Что, в свою очередь, выдает ошибку, когда служба wcf пытается декодировать сообщение. Я думаю, что служба интерпретирует содержимое anyObj как массив, который не может быть неявно преобразован в базовый объект?

При установке аргумента anyObj (типа Object) экземпляру ClassB кажется, что информация о типе теряется. Правильное ли это поведение? У меня создалось впечатление, что даже если вы можете установить переменную суперкласса для ссылки на один из его подклассов, информация о типе подкласса должна быть сохранена и, следовательно, также включена в сериализованное представление этого объекта.

РЕДАКТИРОВАТЬ Похоже, что сериализатор FlashBuilder4 удаляет информацию о конкретном типе и пространстве имен из свойства типа Object при отправке обратно в службу wcf, которая затем не может десериализовать то, что выглядит как массив. Кроме того, при импорте файла WSDL в FB4 наследование VO теряется, поскольку они в конечном итоге расширяют EventDispatcher, чтобы сделать его доступным для привязки.

РЕШЕНИЕ Моим решением было изменить тактику и перейти к удаленному взаимодействию с AMF, реализованному в .NET с использованием FluorineFx,официального веб-сайта FluorineFx, который прекрасно работает и имеет приятный побочный эффект снижения потребления полосы пропускания из-за передачи данных в виде массива байтов.

Я полагаю, что WebORB,официальный сайтWebORB, также можно использовать для реализации AMF в .net, но я еще не пробовал.

Ответ №1:

Вы не можете использовать «любой» объект. Вы всегда должны явно описывать, какие типы разрешены. Проверьте KnownTypeAttribute и ServiceKnownTypeAttribute или DataContractResolver (у меня пока нет слишком большого опыта работы с этим). Если вам действительно нужно отправить произвольные данные и вы не можете заранее определить все возможные объекты, используйте вместо этого XElement. В xsd это будет описано как xsd: any.

Комментарии:

1. Ах да! я пропустил это в демонстрации проблемы, но, к сожалению, не в реальном проекте.

Ответ №2:

  1. Для всех типов объектов, которые вы отправляете по сети, вам необходимо установить атрибут с именем [DataContract]

    [DataContract] открытый класс ClassA { свойство общедоступной строки 1; }

  2. Вместо использования базового типа (object) вам следует использовать базовый класс и использовать атрибут [KnownType]

    [ServiceContract(пространство имен = «EP2ProblemDemo1»)] общедоступный интерфейс IService { [OperationContract] ClassC GetC(ClassD ClassB); }

    [KnownType(typeof(ClassA)), KnownType(typeof(ClassB))] открытый класс ClassD { }

Надеюсь, это поможет

Комментарии:

1. Спасибо за быстрый ответ! Похоже, я собрал довольно плохую демонстрацию, поскольку эти пункты действительны и реализованы в реальном проекте.