Написание клиента C# для использования веб-службы Java, возвращающей массив объектов.
-
09-06-2019 - |
Вопрос
Я пишу клиент C#, который вызывает веб-службу, написанную на Java (другим человеком).Я добавил веб-ссылку на свой клиент и могу нормально вызывать методы в веб-службе.
Служба была изменена и теперь возвращает массив объектов, а клиент неправильно анализирует возвращенное сообщение SOAP.
MyResponse[] MyFunc(string p)
class MyResponse
{
long id;
string reason;
}
Когда мой сгенерированный прокси-сервер C# вызывает веб-службу (используя SoapHttpClientProtocol.Invoke), я ожидаю массив MyResponse[] длиной 1, т.е. один элемент.После вызова Invoke я получаю элемент с id=0 и Reason=null, независимо от того, что на самом деле возвращает служба.Используя анализатор пакетов, я вижу, что служба возвращает то, что выглядит как законное мыльное сообщение с идентификатором и причиной, установленными в ненулевые значения.
Есть ли какой-нибудь трюк, позволяющий клиенту C# вызвать веб-службу Java, которая возвращает someobject[] ?При необходимости я буду работать над получением очищенной демо-версии.
Редактировать:Это веб-ссылка через «Добавить веб-ссылку...».ВС 2005, .NET 3.0.
Решение
Прошло много времени, но я, кажется, помню, что у меня были проблемы с небольшими различиями в том, как обрабатывались пространства имен по умолчанию между веб-службами .Net и Java.
Дважды проверьте сгенерированный прокси-класс C# и все объявленные внутри него пространства имен (особенно значения по умолчанию xmlns="") на соответствие ожиданиям службы Java.Вероятно, будут очень тонкие различия, которые вам придется воссоздать.
В этом случае вам потребуется предоставить дополнительные объявления пространства имен в атрибутах C#.
Другие советы
Благодаря Сианю у меня есть решение.
В wsdl службы включена строка
<import namespace="http://mynamespace.company.com"/>
Мыло, которое клиент отправил на сервер, имело на всех элементах данных следующий атрибут:
xmlns="http://mynamespace.company.com"
Но полезные данные XML ответа (от службы обратно клиенту) сделали нет включить это пространство имен.Повозившись с HTTP-ответом (который я получил с помощью WireShark), я заметил, что прокси-класс .NET правильно воспринимает значения MyResponse, если я принудительно добавляю атрибут xmlns к каждому возвращаемому элементу данных.
Если не считать изменения службы, которую я не контролирую, обходным путем является редактирование сгенерированного VS прокси-класса (например, Reference.cs) и поиск таких строк:
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://mynamespace.company.com")]
public partial class MyResponse {
и закомментируйте строку атрибута XmlType.Это заставит CLR искать элементы ответа в пространстве имен по умолчанию, а не в том, который указан в wsdl.Вам придется повторять это каждый раз, когда вы обновляете ссылку, но, по крайней мере, это работает.
Судя по вашему вопросу, похоже, что в какой-то момент у вас работал клиент, а затем сервис был изменен, чтобы он возвращал массив.Обязательно повторно сгенерируйте прокси-сервер, чтобы возвращенное сообщение SOAP было десериализовано на клиенте.Было неясно, сделали ли вы это, просто чтобы убедиться.