Настройте 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 способа:
- Конвертировать данные в список в ваших методах сохранения на стороне клиента
Изменить тип недвижимости:
public IList<int> SomeList;
в
public List<int> SomeList;
- Подход, который вы показали выше (изменение типа по назначению).
- Реализуйте IDataContractSurrogate. Но вам придется применить поведение на стороне клиента.