Passando coleção recursiva através do WCF
-
26-09-2019 - |
Pergunta
Quero passar um conjunto de dados bastante genérico por meio de um método WCF. Os dados são basicamente apenas um conjunto hierárquico de pares de chave/valor, mas estão aninhados para um nível arbitrário. Originalmente, pensei em passá -lo como uma única corda e fazer XML ou JSON ou codificação/decodificação semelhante em cada extremidade, mas como o transporte do WCF é XML de qualquer maneira, que parecia um pouco bobo, então espero que haja uma maneira de passar por isso "naturalmente".
O método é bastante direto:
[OperationContract]
void ProcessData(DataTree tree);
com:
public class DataTree : Dictionary<string, DataTree>
{
}
Tudo isso compila bem, mas quando tento executar o serviço, ele trava com uma StackOverflowException em DataContract.getStableName.
Eu tentei colocar um [CollectionDataContract]
atributo no DataTree
classe e especificando explicitamente todos os nomes, mas isso não parecia fazer nenhuma diferença.
Eu também tentei colocar um [DataContract]
nele, mas então falha ainda mais cedo porque Dictionary
é ISerializable
.
Alguma ideia? Existe uma maneira melhor de fazer isso?
Solução 2
Como se viu, outro requisito surgiu (especificando um valor simples para um nó, além de uma lista de crianças), então acabei definindo um tipo de criança de qualquer maneira, o que parece ter deixado o WCF feliz com isso:
[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; }
}
Outras dicas
Para grandes árvores de objetos no passado, eu mesmo serializei os dados para uma matriz de bytes que é enviada com o WCF (e o WCF não precisa ser SOAP/XML se você tiver WCF em ambas as extremidades) e depois o desapego manualmente o fim do recebimento.
Basicamente, crie um Serialize(BinaryWriter writer)
e DeSerialize(BinaryReader reader)
Para as aulas em questão que seriam serializadas e passa o escritor/leitor para os objetos infantis para a serialização recursiva.
Você também pode procurar usar Protobuf-Net para serialização/deserialização. Como o transporte na sua chamada WCF, ou manualmente, e passando uma matriz de bytes sobre o fio.