Passing recursive collection through WCF

三世轮回 提交于 2019-12-11 02:34:20

问题


I want to pass a fairly generic set of data through a WCF method. The data is basically just a hierarchical set of key/value pairs, but it's nested to an arbitrary level. I originally considered passing it though as a single string and doing XML or JSON or similar encoding/decoding at either end, but since the WCF transport is XML anyway that seemed a little silly, so I'm hoping there's a way to pass it through "naturally".

The method is fairly straightforward:

[OperationContract]
void ProcessData(DataTree tree);

with:

public class DataTree : Dictionary<string, DataTree>
{
}

This all compiles fine, but when I try to run the service it crashes with a StackOverflowException under DataContract.GetStableName.

I've tried putting a [CollectionDataContract] attribute on the DataTree class and explicitly specifying all the names, but that didn't seem to make any difference.

I've also tried putting a [DataContract] on it, but then it fails even earlier because Dictionary is ISerializable.

Any ideas? Is there a better way to do this?


回答1:


For large object trees in the past I have serialized the data myself to a byte array which is sent over with WCF (and WCF don't have to be SOAP/XML if you have WCF in both ends), and then deserialized it manually on the receiving end.

Basically create a Serialize(BinaryWriter writer) and DeSerialize(BinaryReader reader) for the classes in question which serializes itself, and passes the writer/reader down to the child objects for recursive serialization.

You could also look into using protobuf-net for serialization/deserialization. Either as the transport on your WCF call, or manually, and passing a byte array over the wire.




回答2:


As it turned out, another requirement came up (specifying a simple value for a node in addition to a list of children), so I ended up defining a child type for it anyway, which appears to have made WCF happy with it:

[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; }
}


来源:https://stackoverflow.com/questions/3625504/passing-recursive-collection-through-wcf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!