我正在尝试使用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吗?如上所述,手动序列化正在起作用。
任何评论都表示赞赏!
答案 0 :(得分:2)
好的,到目前为止,我已经提出了两个解决方案。
我已经在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的评论 - 当然,欢迎大家!