使用protobuf-net在WCF中序列化数组

时间:2014-03-19 14:40:48

标签: c# arrays wcf serialization protobuf-net

我正在尝试使用protobuf-net通过WCF序列化我的数据对象数组。

如果我手动序列化我的数据对象数组,它会成功运行:

var proto = Serializer.CreateFormatter<DataType[]>();

比普通二进制文件DataContractSerializer更快更小 - 这就是为什么我要使用它!

&#39;数据类型&#39; class只是一个例子 - 我有很多这样的例子。当我的服务响应只是一个对象时,一切正常。

但是当我的服务返回一个对象数组时,它似乎不知道该做什么并使用普通的DataContractSerializer

应用ProtoBehavior:

endpoint.Behaviors.Add(new ProtoBuf.ServiceModel.ProtoEndpointBehavior());

我的数据对象或多或少是这样的:

[Serializable]
[DataContract]
[ProtoContract]
public class DataType
{
    [DataMember(EmitDefaultValue = false, Name = "K")]
    [ProtoMember(1)]
    public string Key { get; set; }

    // many more to come
}

这基本上就是我的服务:

[ServiceContract(CallbackContract = typeof(IBaseDataObjectUpdate), SessionMode = SessionMode.Required)]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypesProvider))]
public interface IDataTypeService
{
    [OperationContract]
    DataType[] Load(Filter[] filter, Guid clientGuid);

    // some more
}

我可以将其追踪到TryCreate中的XmlProtoSerializer。电话:

int key = GetKey(model, ref type, out isList);

不会返回有效密钥,因此不会创建XmlProtoSerializer

这解释了这种行为,但我的选择是什么?

我找到了Marc Gravell的旧答案,他建议创建一个由Array组成的对象。但是从2011年开始它可能已经过时了: https://stackoverflow.com/a/6270267/2243584

或者我可以手动将模型添加到protobuf-net吗?如上所述,手动序列化正在起作用。

任何评论都表示赞赏!

1 个答案:

答案 0 :(得分:2)

好的,到目前为止,我已经提出了两个解决方案。

  1. 不要使用数组!它适用于任何其他集合。这让我调查并引导解决方案:
  2. 支持protobuf-net中的数组
  3. 我已经在TypeMode类中调整了方法internal static Type GetListItemType(TypeModel model, Type listType),如下所示:

    if (listType.IsArray)  // NEW
    {
      if (listType.GetElementType() == typeof(byte))
        return null;
    }
    if (listType == model.MapType(typeof(string)) // || listType.IsArray // CHANGED!!!
      || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) return null;
    

    我想我确实找出了排除数组的原因。因为如果你支持byte [],最终将数据发送到线路时会遇到一些问题。在处理byte []时,至少我在编码工厂中遇到了一些Assert和exception。

    因为我不知道解决方案Nr的副作用。 2 - 我坚持使用解决方案Nr。 1。

    尽管如此,我非常热衷于Marc的评论 - 当然,欢迎大家!