веб-сервис не может сериализовать интерфейс - PullRequest
9 голосов
/ 18 марта 2009

У меня есть такой интерфейс:

public interface IDocument : ISerializable
{
    Boolean HasBeenUploaded { get; set; }
    void ISerializable.GetObjectData(SerializationInfo, StreamingContext) { }
}

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

public class DCService : System.Web.Services.WebService
{
    [WebMethod]
    public Boolean ReceiveDocument(IDocument document)
    {
        DBIO io = new DBIO();

        return io.InsertIntoDB(document); // does nothing; just returns true
    }
}

Я получаю это при попытке запустить: «Не удается сериализовать интерфейс IDocument»

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

edit> Если я создаю отдельные веб-методы, которые принимают объекты, которые реализуют интерфейс, он работает нормально, но это ослабляет контракт между клиентом / сервером (и подрывает цель иметь интерфейс в первую очередь)

Ответы [ 3 ]

7 голосов
/ 18 марта 2009

Вам может понадобиться использовать атрибут XmlInclude для вашего веб-метода. Пример можно найти здесь . Мы уже сталкивались с этой проблемой ранее и добавили атрибуты XmlInclude и для нашего прокси-класса веб-службы на клиенте, и для некоторых методов веб-службы.

[WebMethod]
[XmlInclude(typeof(MyDocument))]
public Boolean ReceiveDocument(IDocument document)
{
    DBIO io = new DBIO();

    return io.InsertIntoDB(document); // does nothing; just returns true
}
1 голос
/ 02 апреля 2009

+ 1 для firedfly, однако следует отметить, что атрибут XmlInclude может добавляться к веб-службе class , а не к каждому методу (или базовому типу, который также является опцией). Я проверил это, и код сгенерирован хорошо, сохраняя структуру наследования.

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

Кстати, это не комментарий к сообщению firedfly, потому что у меня недостаточно репутации, чтобы комментировать

1 голос
/ 18 марта 2009

Asp.net должен иметь возможность указать, какой именно класс он будет создавать при вызове этого метода. Вот почему он работает при определении нескольких методов с конкретными классами, то есть вызов скажет вам, какой класс использовать.

Подумайте, хотите ли вы, чтобы клиент отправлял один и тот же набор информации для любого документа, или вам действительно нужно иметь возможность отправлять различную информацию для разных документов. В последующем клиенту необходимо знать классы, реализующие IDocument, и вы делаете это с помощью XmlInclude (как опубликовано в firedfly).

Если вы вместо этого хотите всегда посылать одну и ту же информацию, а не о конкретных классах, определите класс с этой информацией, и именно это вы получите в методах. Если вам нужно поиграть с IDocument в остальном коде сервиса, используйте соответствующую логику в сервисе, которая получает вам экземпляр IDocument, используя полученные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...