ArgumentOutOfRangeException при десериализации запроса protobuf-net

После развертывания новой версии одного из наших приложений мы начали видеть несколько исключений ArgumentOutOfRangeException из WebApiContrib/protobuf-net. Это происходило один раз раньше, но происходило чаще (5-10 раз или около того) после развертывания. Это произошло только по нескольким общим запросам, и я не смог воспроизвести это локально или в других средах. Ошибки произошли на нескольких машинах.

Вызывающие приложения устанавливают библиотеку классов Nuget с контрактом protobuf, и этот контракт был обновлен в вызываемом приложении в этом выпуске. Некоторые свойства были удалены (без изменения 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" />

Обновить:

  • Мы попытались удалить ProtobufFormatter из WebApiContrib.Formatting и вместо этого выполнить десериализацию непосредственно в коде с помощью Serializer.Deserialize. Это не имело никакого эффекта.
  • Затем мы добавили повторные попытки. Сброс потока. Установите в 0 и снова десериализируйте. Это работает.
  • Теперь мы регистрируем Request.Content как строку base64. Этот контент десериализуется очень хорошо, и при попытке воспроизвести его локально ничего не происходит, даже с тысячами запросов.

0 ответов

Другие вопросы по тегам