DataContractSerializer и десериализация типов ответов веб-сервисов - PullRequest
3 голосов
/ 18 марта 2010

Я использую вызов веб-сервисов и использую сервисную ссылку, созданную WCF на клиенте. Я сохранил ответы XML, полученные от службы тестирования, на диск (без конвертов SOAP и тегов body). Я хотел бы загрузить их с диска и создать из них объекты. Давайте возьмем следующий метод из моего веб-сервиса:

SomeMethodResponse SomeMethod(SomeMethodRequest req)

Я вручную (через интерфейс SOAP) сохраняю ответ на диск в файл, Пример ответа:

<SomeMethodResponse xmlns="http://myNamespace">
    <SomeMember1>value</SomeMember1>
</SomeMethodResponse>

Затем я пытаюсь десериализовать объект из файла, используя:

DataContractSerializer dcs = 
  new DataContractSerializer(typeof(SomeMethodResponse))

Это терпит неудачу - сериализатор жалуется с ошибкой, что он ожидает элемент в пространстве имен 'http://schemas.datacontract.org/2004/07',, но обнаружил элемент в' http://myNamespace'.

Вопрос: Почему DataContractSerializer не использует пространство имен, которое объявлено в SomeMethodResponseType с XmlTypeAttribute(Namespace="http://myNamespace")?

Я могу обойти это, явно предоставив пространство имен и корневой элемент конструктору DataContractSerializer. Но тогда это терпит неудачу с сообщением, подобным:

Ошибка в строке X позиции Y (последняя строка XML-документа). 'EndElement' 'SomeMethodResponse
из пространства имен 'httpmyNapespace' не ожидается. Ожидается элемент 'someNameField'.

SomeName - это элемент в XSD, который использует веб-служба. Это также свойство типа SomeMethodResponse, поддерживаемое приватным полем с именем someNameField. Похоже, DataContractSerializer пытается десериализовать поля в дополнение к свойствам.

Как я могу десертировать XML, который я сохранил с диска, и вернуть объект того же типа, который возвращает SomeMethod?

Спасибо, Matra

Ответы [ 2 ]

5 голосов
/ 18 марта 2010

Позвольте мне ответить на мой собственный вопрос: причина второго сообщения об ошибке в том, что на самом деле svcUtil тихо решил использовать XmlSerializer вместо DataContractSerializer. Я нашел это, прочитав справку XmlTypeAttribute - MSDn сообщает Управляет схемой XML, которая генерируется, когда цель атрибута сериализуется XmlSerializer. ;-) Итак, мы вернулись к старому, XmlSerializer

5 голосов
/ 18 марта 2010

Ваш ответ XML явно имеет пространство имен XML:

<SomeMethodResponse xmlns="http://myNamespace">
    <SomeMember1>value</SomeMember1>
</SomeMethodResponse xmlns="http://myNamespace">

поэтому, чтобы правильно прочитать и десериализовать это, вам нужно сообщить вашему DataContractSerializer об этом пространстве имен:

DataContractSerializer dcs = 
    new DataContractSerializer(typeof(SomeMethodResponse),
                               "SomeMethodResponse", "http://myNamespace")

Указав это пространство имен XML по умолчанию в конструкторе, он должен теперь иметь возможность читать и десериализовать этот XML.

Другая ошибка, которую вы получаете:

Ошибка в строке X, позиция Y (последняя строка XML-документа). 'EndElement' «SomeMethodResponse из пространства имен« httpmyNapespace »не ожидается. Ожидается элемент 'someNameField'.

вызвано очень необычным и никогда ранее не замеченным фактом, что у вашего конечного элемента есть пространство имен ........

</SomeMethodResponse xmlns="http://myNamespace">

просто удалите лишнее пространство имен, и все будет в порядке!

</SomeMethodResponse>
...