Передача рекурсивной коллекции через WCF
Я хочу передать довольно общий набор данных через метод WCF. Данные в основном представляют собой просто иерархический набор пар ключ / значение, но они вложены в произвольный уровень. Первоначально я думал о передаче его в виде одной строки и выполнении XML, JSON или аналогичного кодирования / декодирования на любом конце, но поскольку транспорт WCF - это XML, в любом случае это выглядит немного глупо, поэтому я надеюсь, что есть способ передать его через "естественно".
Метод довольно прост:
[OperationContract]
void ProcessData(DataTree tree);
с:
public class DataTree : Dictionary<string, DataTree>
{
}
Все это прекрасно компилируется, но когда я пытаюсь запустить службу, происходит сбой с StackruException в DataContract.GetStableName.
Я пытался положить [CollectionDataContract]
атрибут на DataTree
класс и явно указав все имена, но это, похоже, не имеет никакого значения.
Я также пытался положить [DataContract]
на этом, но тогда это терпит неудачу даже раньше, потому что Dictionary
является ISerializable
,
Есть идеи? Есть лучший способ сделать это?
2 ответа
Как оказалось, появилось другое требование (указав простое значение для узла в дополнение к списку дочерних элементов), поэтому я все равно определил дочерний тип для него, что, по-видимому, порадовало WCF:
[CollectionDataContract(IsReference = true, ItemName = "Param",
KeyName = "Name", ValueName = "Data")]
public class DataTree : Dictionary<string, DataTreeEntry>
{
}
[DataContract]
public class DataTreeEntry
{
[DataMember]
public string Value { get; set; }
[DataMember]
public DataTree Children { get; set; }
}
Для больших деревьев объектов в прошлом я сам сериализировал данные в байтовый массив, который отправляется с помощью WCF (и WCF не обязательно должен быть SOAP/XML, если у вас есть WCF на обоих концах), а затем десериализовал их вручную принимающая сторона.
В основном создать Serialize(BinaryWriter writer)
а также DeSerialize(BinaryReader reader)
для рассматриваемых классов, который сериализует себя и передает писателя / читателя дочерним объектам для рекурсивной сериализации.
Вы также можете изучить использование protobuf-net для сериализации / десериализации. Либо в качестве транспорта на ваш вызов WCF, либо вручную, и передачи байтового массива по проводам.