.net Protobuf net memcache提供程序反序列化时出现null类型错误
我正在使用protobuf net memcache提供程序的最新protobuf net lib。我需要序列化自定义类型MyClass的列表.net Protobuf net memcache提供程序反序列化时出现null类型错误,.net,memcached,protobuf-net,.net,Memcached,Protobuf Net,我正在使用protobuf net memcache提供程序的最新protobuf net lib。我需要序列化自定义类型MyClass的列表 [ProtoContract] public class MyClass{ [ProtoMember(1)] public int a {get; set;} [ProtoMember(2)] public int b {get; set;} } 因此,我需要存储/检索: List<MyClass> myList 要重现该
[ProtoContract]
public class MyClass{
[ProtoMember(1)]
public int a {get; set;}
[ProtoMember(2)]
public int b {get; set;}
}
因此,我需要存储/检索:
List<MyClass> myList
要重现该错误,请执行以下操作:
ProtoBuf.Meta.TypeModel.PrepareDeserialize(Object value, Type& type) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:592
ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:577
ProtoBuf.Caching.Enyim.NetTranscoder.Enyim.Caching.Memcached.ITranscoder.Deserialize(CacheItem item) in c:\Users\akureniov\work\protobuf-net-1\protobuf-net.Enyim\protobuf-net.Enyim\ProtoTranscoder.cs:109
Enyim.Caching.MemcachedClient.PerformTryGet(String key, UInt64& cas, Object& value) +179
Enyim.Caching.MemcachedClient.TryGet(String key, Object& value) +42
Enyim.Caching.MemcachedClient.Get(String key) +15
我认为memcache不理解
ProtoContract
,尝试将它们标记为DataContract
,我们在ProtoTranscoder中的类型修剪中发现了“bug”。cs:NetTranscoder:void WriteType(MemoryStream ms,type type type)。此代码块会导致错误,因为它剪切太多:
int i = typeName.IndexOf(','); // first split
if (i >= 0) { i = typeName.IndexOf(',', i + 1); } // second split
if (i >= 0) { typeName = typeName.Substring(0, i); } // extract type/assembly only
它对简单类型很有效,但在列表、字典等方面失败
为了避免这种情况,最好使用regexp来剪切非必要信息(如文化、publickkeytoken等)。因此,这里有一个替代品(需要用这个替代上面的行),非常粗鲁,但在大多数情况下都有效:
typeName = Regex.Replace(typeName, @", Version=\d+.\d+.\d+.\d+", string.Empty);
typeName = Regex.Replace(typeName, @", Culture=\w+", string.Empty);
typeName = Regex.Replace(typeName, @", PublicKeyToken=\w+", string.Empty);
此regexp不会剪切自定义类型所需的类型程序集。但对于标准类型,它是mscorlib
,在大多数情况下,可以通过添加另一行来安全删除:
typeName = Regex.Replace(typeName, @", mscorlib", string.Empty);
请具体说明:您正在使用哪些dll版本?“最新的protobuf网络库”不包括enyim转码器(“Extensions”项目没有针对v2进行修改,也没有构建AFAIK,尽管它在我的列表中)。那么:您使用的是旧版本的转码器吗?你修补过“扩展”吗?或者您是手动存储类型吗?您是否碰巧使用了
ProtoTranscoder
NuGet包?我使用的是protobuf-net-r622 lib和protobuf-enyim模块,它们是从svn的源代码编译而来的(它作为单独的项目进入svn)。Nuget软件包不适用于couchbase enyim。缓存库具有不同的publick密钥。您能准确地告诉我您正在使用/从源代码编译的“protobuf enyim模块”吗?没有它很难评论…它位于您的svn中。名为“protobuf net.Enyim”的文件夹。我已经将参考protobuf网络库更新为版本r622,然后编译了它。另外,我将很快更新我的第一篇文章,更深入地跟踪错误;如果是这样的话,enyim可以做任何它需要的事情。段落应该说“汇编”,而不是“名称空间”-但是看起来不错,谢谢!稍后我会考虑合并它。非常感谢。修复了最后一段。谢谢此外,我在复杂的列表和字典上测试了我的代码,似乎效果很好。删除mscorlib也很好。这个问题解决了吗?我想我在protobuf net v2.0.0.621中看到了这个问题。这也很奇怪——我可以成功地存储一些列表,但不能存储其他列表。它似乎取决于列表的泛型类型。正如我看到的存档打开关闭。网站没有改变。因此,解决这个问题的方法是:从svn获取源代码,替换这些行并编译它。到目前为止,这个修复程序在我们的项目中可以很好地处理我们所有的类型。奇怪的是,我获取了源代码(protobuf net和protobuf net.enyim),但不能用它序列化/反序列化普通的[Serializable]
类(即:没有[ProtoContract]
或[DataContract]
属性)。它与Protobuf-net和Protobuf-net.Enyim的nuget版本一起工作,但不是从我下载的源代码。通过pf-n.enyim单元测试,我发现我的类型未能通过TypeModel.cancontractType
。它适用于nuget版本,而不是我的开源版本。我错过了什么?(protobuf Net的标准.Net 4版本)
typeName = Regex.Replace(typeName, @", mscorlib", string.Empty);