反序列化protobuf-net请求时的ArgumentOutOfRangeException

时间:2017-03-06 14:10:32

标签: asp.net protobuf-net web-api-contrib

在部署我们的某个应用程序的新版本后,我们开始从WebApiContrib / protobuf-net看到多个ArgumentOutOfRangeExceptions。它曾经发生过一次,但是在部署之后发生的频率更高(5-10次左右)。它只发生在一些总请求中,我无法在本地或其他环境中重现。错误发生在多台机器上。

调用应用程序使用protobuf合约安装Nuget类库,此合同已在此版本的被调用应用程序中更新。一些属性被删除(不更改ProtoMember.Tag),一些属性被标记为IsRequired = false而不是true。

是否有人对可能失败的内容或我们如何进一步诊断它有任何见解?

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: offset
   at System.Web.HttpInputStream.Seek(Int64 offset, SeekOrigin origin)
   at System.Web.Http.WebHost.SeekableBufferedRequestStream.Seek(Int64 offset, SeekOrigin origin)
   at ProtoBuf.ProtoReader.Seek(Stream source, Int32 count, Byte[] buffer) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 1143
   at proto_14(Object , ProtoReader )
   at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 579
   at proto_2(Object , ProtoReader )
   at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 704
   at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 588
   at WebApiContrib.Formatting.ProtoBufFormatter.ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Http.HttpContentExtensions.<ReadAsAsyncCore>d__0`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.ModelBinding.FormatterParameterBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()

版本:

<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net452" />
<package id="protobuf-net" version="2.0.0.668" targetFramework="net452" />
<package id="WebApiContrib.Formatting.ProtoBuf" version="0.9.5.0" targetFramework="net452" />

更新

  • 我们尝试从WebApiContrib.Formatting中删除ProtobufFormatter,而是直接在使用Serializer.Deserialize的代码中进行反序列化。那没有效果。
  • 然后我们添加了重试次数。将stream.Position重置为0并再次反序列化。这很有效。
  • 我们现在将Request.Content记录为base64字符串。该内容反序列化得很好,当尝试在本地重现它时,即使有数千个请求,也没有任何失败。

0 个答案:

没有答案