WCF DataContract - обработка производного класса как базового класса для сериализации - PullRequest
1 голос
/ 09 февраля 2012

У меня есть простой контракт данных:

[DataContract]
public class MyData
{
   [DataMember]
   public string AwesomeData { get; set; }
}

И контракт на обслуживание:

[ServiceContract]
public interface IMyDataService
{
   [OperationContract]
   MyData GetAwesomeData();
}

В сборке на стороне сервера я создаю производный класс для выполнения обработки:

public class MyDataWithInnerds: MyData
{
   public MyDataWithInnerds(object intializationStuff)
   {
      AwesomeData = Hypermaxulate(initializationStuff);
   }
}

и реализация сервиса:

public class MyDataService: IMyDataService
{
  public MyData GetAwesomeData()
  {
     return new MyDataWithInnerds(HupnerRayvakManager.GetInitializationStuff());
  }
}

MyDataWithInnerds - это просто функциональная реализация контракта MyData, основанного исключительно на данных.

Есть ли в любом случае без украшения MyData и ссылки MyDataWithInnerds, чтобы сказать сериализатору сериализовать MyDataWithInnerds как MyData?Сборка с MyData также предоставляется клиентам.Я не хочу, чтобы на стороне сервера ссылались только на MyDataWithInnerds.

Мне не нужно десериализовать его в MyDataWithInnerds.Я предполагаю, что мне нужно будет клонировать экземпляр MyDataWithInnerds в экземпляр MyData, чтобы он не имел никакой информации о типе, связанной с MyDataWithInnerds, но было бы очень эффективно не делать этого и просто сообщить сериализатору«Я знаю, что это MyDataWithInnerds, но вы можете просто обращаться с ним как с базовыми MyData»

Спасибо, Майк

РЕДАКТИРОВАТЬ

Я смогдобавить следующее в мой конфигурационный файл на сервере:

  <system.runtime.serialization>
    <dataContractSerializer>
      <declaredTypes>
        <add type="MyClientLib.MyData, MyClientLib">
          <knownType type="MyServerLib.MyDataWithInnerds, MyServerLib"/>
        </add>
      </declaredTypes>
    </dataContractSerializer>
  </system.runtime.serialization>

И это заставит сериализацию работать правильно.

Это просто оставляет два побочных вопроса:

  1. В моей сериализации JSON я получаю член "__type", который содержит тип производного класса.Могу ли я удалить это?
  2. Есть ли декларативный способ сделать на объектах сервера (не MyData), что я сделал в конфигурации (добавив KnownType's)?

Спасибо2,Mike

1 Ответ

1 голос
/ 16 февраля 2012

В конце я создал конструктор копирования для своего базового класса и вместо возврата производного класса (в качестве базового класса) я возвращаю новый базовый (производный).

[DataContract]
public class MyData
{
   [DataMember]
   public string AwesomeData { get; set; }

   public MyData(MyData obj)
   {
       AwesomeData = obj.AwesomeData;
   }
}

Реализация службы становится:

public class MyDataService: IMyDataService
{
  public MyData GetAwesomeData()
  {
     MyDataWithInnerds data = 
         new MyDataWithInnerds(HupnerRayvakManager.GetInitializationStuff());
     return new MyData(data);
  }
}

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

...