WCF DataContract исключает DataMembers из сериализации в производных классах - PullRequest
7 голосов
/ 26 августа 2010

У меня есть базовый класс со свойствами DataMember.У меня также есть производный класс со свойствами DataMember.В моем проекте WCF я возвращаю производный класс.Есть ли способ предотвратить сериализацию члена моего базового класса?Вот пример кода:

public class BaseClass
{
    public string ShortDescription {get;set;}
    public string LongDescription {get;set;}
}

public class DerivedClass : BaseClass
{
    public List<Description> Descriptions {get;set;}
}

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

public class DerivedClass : BaseClass
{
    [DataMember]
    public List<Description> Descriptions {get;set;}

    // override the base class members
    [IgnoreDataMember]    
    public override string ShortDescription {get;set;}
    [IgnoreDataMember]
    public override string LongDescription {get;set;}
}

и

public class DerivedClass : BaseClass
{
    [DataMember]
    public List<Description> Descriptions {get;set;}

    // shadow the base class members
    [IgnoreDataMember]    
    public new string ShortDescription {get;set;}
    [IgnoreDataMember]
    public new string LongDescription {get;set;}
}

Ни один из этих подходов не сработал.Тип «DerivedClass» при выводе в WSDL по-прежнему содержит «игнорируемые» члены типа базового класса.

Вы можете удивиться, почему я не просто изменяю базовый класс.Это потому, что я все еще использую базовый класс в его первоначальном виде в качестве предыдущей версии типа для WSDL для поддержки обратной совместимости для потребителей.Таким образом, у меня может быть вызов v1000, который возвращает BaseClass, и вызов V1010, который возвращает DerivedClass.Я могу добавлять и изменять функциональные возможности в DerivedClass все, что мне нужно, без потенциального влияния на потребителей функциональности v1000.

Ответы [ 3 ]

6 голосов
/ 21 марта 2011

Попробуйте добавить атрибут [DataContract] для обоих классов.Это скажет сериализатору взглянуть на атрибуты [DataMember] и [IgnoreDataMember].Без указания класса с помощью [DataContract] все открытые члены сериализуются.

[DataContract]
public class BaseClass
{
    [IgnoreDataMember]
    public string ShortDescription {get;set;}

    [IgnoreDataMember]
    public string LongDescription {get;set;}
}

[DataContract]
public class DerivedClass : BaseClass
{
    [DataMember]
    public List<Description> Descriptions {get;set;}
}

Кроме того, было бы еще лучше добавить пространство имен в ваши контракты данных, указав его в [DataContract (Namespace = "... ")] атрибут.Это сломало бы старых клиентов, звонивших на ваш обновленный сервис.

2 голосов
/ 15 января 2011

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

public class BaseClass
{
    // leave this guy empty
}

public class DerivedClassVersion1 : BaseClass
{
    [DataMember]
    public string ShortDescription {get;set;}

    [DataMember]
    public string LongDescription {get;set;}
}

public class DerivedClassVersion2 : BaseClass
{
    [DataMember]
    public List<Description> Descriptions {get;set;}
}

Badda bing!Довольно просто, но это то, что мне было нужно.

0 голосов
/ 26 августа 2010

Попробуйте это:

public class BaseClass
{
    [DataMember]
    public virtual string ShortDescription {get;set;}

    [DataMember]
    public virtual string LongDescription {get;set;}
}

public class DerivedClass : BaseClass
{
    [DataMember]
    public List<Description> Descriptions {get;set;}

    public override string ShortDescription {get;set;}
    public override string LongDescription {get;set;}
}

РЕДАКТИРОВАТЬ: Возможно, использование контрактов сообщений для точного контроля сериализации может работать: http://msdn.microsoft.com/en-us/library/ms730255.aspx

В противном случае, вы также можете посмотреть на реализацию 'Маршрутизатор WCF'который позволит вам использовать одну и ту же конечную точку, но направлять разные версии к разным сервисам.

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