Передача объекта через веб-сервис с SOAP в C # - PullRequest
1 голос
/ 07 декабря 2011

Я работаю над приложением сервер-клиент.Связь осуществляется с использованием веб-сервисов.И сервер, и клиент написаны на C #.Я боролся с этим уже несколько дней, но не смог решить.

У меня проблема с отправкой сложных классов через веб-сервис - я пробовал много вещей, но ни один из них не работает.

Каждый веб-метод возвращает класс ServiceResult, который выглядит следующим образом:

    public class ServiceResult
    {
        public ResultStatus Status;
        public object ResultObject;

        public ServiceResult(ResultStatus status, object resultObject)
        {
            Status = status;
            ResultObject = resultObject;
        }
    }

ResultStatus - это enum, ResultObject - это фактическое возвращаемое значение.Проблема возникла, когда я пытался отправить сложные классы через веб-сервис.

Например, у меня есть абстрактный класс Job, в котором есть закрытые элементы.

public abstract class Job : IComparable<Job>
{
    public static readonly int DefaultDelay = 5000;

    private int _jobID;
    private int _referringID;
    private JobType _jobType;
    protected JobState _jobState;
    private JobPriority _jobPriority;
    [...]   
}

Но когда я пытаюсь отправить класскоторый наследует класс Job (назовем его JobA) через webmethod У меня есть ошибки.Поскольку у меня нет явного типа возврата JobA в любом веб-методе, при вызове моего веб-метода я получаю ошибку:

System.Web.Services.Protocols.SoapException: Серверу не удалось обработать запрос.---> System.InvalidOperationException: при создании XML-документа произошла ошибка.---> System.InvalidOperationException: тип Job [] не может использоваться в этом контексте.

Это было о первой ошибке.Теперь есть другая проблема с другим классом, где ошибка выглядит следующим образом (опять же, при вызове веб-метода):

System.Web.Services.Protocols.SoapException: Серверу не удалось обработать запрос.---> System.InvalidOperationException: при создании XML-документа произошла ошибка.---> System.InvalidOperationException: тип не ожидался.Используйте атрибут XmlInclude или SoapInclude, чтобы указать типы, которые статически не известны.

Когда я добавляю [SoapInclude (typeof (MyClass))]], это не имеет никакого значения, но вместо этого использование XmlInclude делает мой ServiceResult.ResultObject.массив XmlNodes.

Я думаю, что обе проблемы связаны с сериализацией, но я не знаю, как их решить.По сути, мой вопрос: как я должен передавать пользовательские объекты с сервера на клиент через webmethod таким образом, чтобы я мог использовать их как объект (я хотел бы привести этот ServiceResult.ResultObject к классу и использовать его как случайный экземплярэтот класс)?Каков наилучший способ сделать это?

Кто-нибудь может предложить какое-либо решение для этого?

1 Ответ

3 голосов
/ 07 декабря 2011

Исходя из исходного сообщения об ошибке, может показаться, что у вас может быть свойство, являющееся массивом или коллекцией Job в классе, который вы пытаетесь сериализовать, что вызовет исключение, которое вы видите.

Если это свойство не предполагается сериализовать, вы можете украсить его атрибутом XmlIgnore.

Кроме того, когда я пытаюсь отладить проблемы с сериализацией веб-службы, я обычно использую XmlSerializer для сериализации экземпляров классов моих веб-служб, прежде чем пытаться подключить их к веб-методам. Иногда вы можете получить более точную информацию о том, что не удалось, и посмотреть сериализованный вывод, чтобы определить, где элементы не могут быть сериализованы, как вы ожидаете.

Вот небольшой тестовый метод, который вы можете использовать для этого:

    /// <summary>
    /// This method serializes objects to an XML string using the XmlSerializer
    /// </summary>
    /// <returns></returns>
    /// <remarks></remarks>
    public string SerializeObjectToXMLString(object theObject)
    {
        // Exceptions are handled by the caller

        using (System.IO.MemoryStream oStream = new System.IO.MemoryStream())
        {
            System.Xml.Serialization.XmlSerializer oSerializer = new System.Xml.Serialization.XmlSerializer(theObject.GetType());

            oSerializer.Serialize(oStream, theObject);

            return Encoding.Default.GetString(oStream.ToArray());
        }
    }
...