WCF DataContract Upcasting - PullRequest
       10

WCF DataContract Upcasting

1 голос
/ 22 июня 2009

Я пытаюсь взять объект datacontract, полученный на сервере, выполнить некоторые манипуляции с ним, а затем вернуть его версию с подтвержденной версией, однако, похоже, она не работает. Я могу заставить его работать, используя атрибуты KnownType или ServiceKnownType, но я не хочу обойти все данные. Ниже приведен пример:

[DataContract]
public class MyBaseObject
{
    [DataMember]
    public int Id { get; set; }
}

[DataContract]
public class MyDerivedObject : MyBaseObject
{
    [DataMember]
    public string Name { get; set; }
}


[ServiceContract(Namespace = "http://My.Web.Service")]
public interface IServiceProvider
{
    [OperationContract]
    List<MyBaseObject> SaveMyObjects(List<MyDerivedObject> myDerivedObjects);
}

public class ServiceProvider : IServiceProvider
{
    public List<MyBaseObject> SaveMyObjects(List<MyDerivedObject> myDerivedObjects)
    {
        ... do some work ...

        myDerivedObjects[0].Id = 123;
        myDerivedObjects[1].Id = 456;
        myDerivedObjects[2].Id = 789;

        ... do some work ...

        return myDerivedObjects.Cast<MyBaseObject>().ToList();
    }
}

У кого-нибудь есть идеи, как заставить это работать без воссоздания новых объектов или использования атрибутов KnownType?

Ответы [ 4 ]

0 голосов
/ 11 мая 2010

Одна из проблем с WCF (и удаленным взаимодействием .net) заключается в том, что они пытаются сделать так, чтобы «передача сообщений» выглядела как вызовы методов.

Это происходит, когда вы пытаетесь использовать слишком много дизайнов типа "oop".

Тот факт, что сообщения представлены классами .net, не сделать все их поведение как .net класс.

См. это и это , для более подробной информации о проблеме утечки абстракции.

Так что вам нужно начать думать о передаче сообщений, а не об объектах при разработке ваших интерфейсов WCF, иначе вы столкнетесь с множеством подобных проблем.

0 голосов
/ 22 июня 2009

Если вы хотите вернуть производные объекты, то всегда будет двусторонняя передача, потому что клиент и служба разделены. Чтобы клиент мог обновить свой собственный список объектов MyBaseObject, ему необходимо десериализовать список объектов MyDerivedObject, полученных с сервера.

Необходимо использовать KnownType и / или ServiceKnownType, поскольку это приводит к добавлению информации этого типа в WSDL, который, в свою очередь, используется клиентом для десериализации сообщений правильного типа.

Для начала, полезный инструмент для тестирования сценария, который вы описали: http://www.wcfstorm.com

0 голосов
/ 08 ноября 2009

Вы можете попытаться создать DataContractSurrogate (IDataContractSurrogate) и вернуть ваш базовый тип для вызова GetDataContractType. Я не совсем уверен, что именно так оно и было задумано, поэтому вам, возможно, будет лучше с «дополнительной работой», но, возможно, я не понимаю масштаб этой дополнительной работы.

0 голосов
/ 22 июня 2009

Думаю, ваша проблема в том, что вы пытаетесь отправить общий список.

Это будет работать, если вы инкапсулируете список в объект. То есть создайте объект с единственным открытым свойством, которое является общим списком.

Вам также необходимо убедиться, что все классы, которые не используются непосредственно в контракте, помечены как сериализуемые.

...