Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ServiceStack中使用ICacheClient和protobuf时的编码/序列化问题_C#_Serialization_Character Encoding_Protobuf Net_<img Src="//i.stack.imgur.com/WM7S8.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">servicestack - Fatal编程技术网 servicestack,C#,Serialization,Character Encoding,Protobuf Net,servicestack" /> servicestack,C#,Serialization,Character Encoding,Protobuf Net,servicestack" />

C# 在ServiceStack中使用ICacheClient和protobuf时的编码/序列化问题

C# 在ServiceStack中使用ICacheClient和protobuf时的编码/序列化问题,c#,serialization,character-encoding,protobuf-net,servicestack,C#,Serialization,Character Encoding,Protobuf Net,servicestack,我正在使用带有protobuf序列化的当前ServiceStack 添加ICacheClient以缓存我的响应时,从缓存客户端发送的二进制应答与没有任何缓存客户端的原始响应具有不同的编码/二进制序列化 这导致了客户端的反序列化问题,在客户端,我使用的是预编译的反序列化程序 例如,在ServiceStack服务器端使用ICacheClient时,此protobuf异常在客户端发生: OverflowException: Number overflow. ProtoBuf.ProtoReader.T

我正在使用带有protobuf序列化的当前ServiceStack

添加ICacheClient以缓存我的响应时,从缓存客户端发送的二进制应答与没有任何缓存客户端的原始响应具有不同的编码/二进制序列化

这导致了客户端的反序列化问题,在客户端,我使用的是预编译的反序列化程序

例如,在ServiceStack服务器端使用ICacheClient时,此protobuf异常在客户端发生:

OverflowException: Number overflow.
ProtoBuf.ProtoReader.TryReadUInt32VariantWithoutMoving (Boolean trimNegative, System.UInt32& value)
ProtoBuf.ProtoReader.ReadUInt32Variant (Boolean trimNegative)
ProtoBuf.ProtoReader.ReadUInt32 () MyModelSerializer.Read (My.Models.MyDataModel , ProtoBuf.ProtoReader )
(我相信这是一个随机的异常,可以肯定还会发生其他异常。以此为例。)

此行为与MemoryCacheClient和Redis cache client相同

这是我初始化protobuf的方式:

ContentTypeFilters.Register(ContentType.ProtoBuf,
                        (reqCtx, res, stream) => ProtoBuf.Serializer.NonGeneric.Serialize(stream, res),
                         ProtoBuf.Serializer.NonGeneric.Deserialize);
缓存客户端的初始化方式如下:

container.Register<ICacheClient>(new MemoryCacheClient());
container.Register(newmemorycacheclient());
(或Redis following)

这就是缓存的protobuf序列化数据(通过连接)与未缓存的数据的外观和区别:

未缓存响应的编码/序列化方式似乎有所不同

我能为这个编码问题做些什么使Redis或内存ICacheClient与protobuf兼容


更新:我进行了一些调查,以下是我的发现:

  • 为了存储在缓存提供程序中(无论是Redis os内存),protobuf二进制流通过HttpResponseFilter->SerializeToString中的StreamReader使用“UTF8无BOM”编码“转换”为字符串,该编码本身通过CacheClientExtensions->cache()调用

  • 第一个问题:CacheClientExtensions->Cache()然后返回字符串to serialized DTO,使得protobuf无法反序列化第一个解决方案:在CacheClientExtensions->Cache()中返回原始DTO。但这只适用于第一个非缓存响应,因为缓存响应尚未正确反序列化。这把我们带到了

  • 第二个问题:再次从缓存中取出数据需要对protobuf的二进制数据进行正确的字符串序列化,以便首先将其放入缓存中。我知道使用via base64会起作用

  • 第三个问题:目前似乎无法在运行时通过HttpResponseFilter->SerializeToString中的StreamReader替换当前流到字符串的转换,对吗

  • 第四个问题:从缓存中取回数据时,必须再次对其进行base64解码


我在翻阅ServiceStack代码,但没有发现实现我的需求的可能性(我真的希望我没有忽略什么)

因此,我对ServiceStack做了一些更改,允许使用自定义TextSerializer,然后使用这些自定义TextSerializer将DTO推送到缓存客户机中,将其序列化为字符串bevor

在这里查看我的差异:

它是为我的目的而工作的,尽管它可能还没有完全测试过,而且还非常专注于protobuf


如果一些ServiceStack忍者能够回顾我正在做的事情,我将不胜感激,也许它最终会成为一个请求。

这听起来主要是ServiceStack;我相信Mythz或其他人很快就会出现,但一如既往:如果我能从protobuf网络方面提供帮助,请有人喊我一声。谢谢@MarcGravel。你同意我的观点,屏幕截图中缓存的(屏幕截图右侧)二进制格式对于protobuf是无效的?老实说,我还没有尝试过分析它(我不是在电脑上),压缩之类的东西可能是一个因素,但是:这听起来像是protobuf net所做的事情之外的东西。不过,有一件事我并不清楚:为什么调用
ContentTypeFilters.Register
时stacktrace会提到
MyModelSerializer
?呵呵,我以为你会记住字节码:)关于MyModelSerializer:那是客户端。很抱歉,我会添加这些信息。如果能使用十六进制计算器和记事本,我可以检查一下。在while循环中更容易启动
ProtoReader
,但是:
while(reader.ReadFieldHeader()>0){reader.SkipField();}
-这将不考虑任何servicestack包装,尽管mythz确认了这个问题,我接受了自己的答案。