Настройте WCF для десериализации массивов как коллекций без svcutil

У меня есть net.tcp Служба WCF и ее клиент, каждая в одной сборке и совместно использующая другую сборку, содержащую интерфейс службы и DTO.

Клиент реализован как прокси для службы с использованием Channel созданный через ChannelFactory:

public ServiceClient : IService
{
   IService _channel;

   public ServiceClient()
   {
      _channel =  new ChannelFactory<IService>("NetTcp_IService")
         .CreateChannel();
   }

   public DTO ServiceMethod()
   {
       return _channel.ServiceMethod();
   }
}

public class DTO
{
   public IList<int> SomeList;
}

Как и ожидалось, SomeList поле DTO, возвращаемое клиентом, является массивом, но я бы хотел, чтобы оно было преобразовано WCF в List, Как вы можете подозревать из описанной установки, я не использую svcutil (или диалоговое окно Add Service Reference), поэтому я не могу использовать configureType,

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

Поэтому в настоящее время я использую обходной путь, который модифицирует DTO для внутреннего создания экземпляра List:

public class DTO
{
   private IList<int> _someList;
   public IList<int> SomeList
   {
      get { return _someList; }
      set {
         if (value != null)
            _someList = new List<int>(value);
         else
            _someList = new List<int>();
      }
   }
}

Однако я бы предпочел этого избежать. Итак, вопрос:

Как я могу настроить десериализацию WCF так, чтобы array преобразуется в ожидаемый List?

Есть ли способ настроить десериализацию через привязку либо в App.config или из кода на Channel создание? Может быть, через ImportOptions.ReferencedCollectionTypes или же CollectionDataContract?

1 ответ

Решение

Есть 4 способа:

  1. Конвертировать данные в список в ваших методах сохранения на стороне клиента

  2. Изменить тип недвижимости:

    public IList<int> SomeList;
    

    в

    public List<int> SomeList;
    
  3. Подход, который вы показали выше (изменение типа по назначению).

  4. Реализуйте IDataContractSurrogate. Но вам придется применить поведение на стороне клиента.
Другие вопросы по тегам