ServiceStack.Text反序列化时自动释放输入流的问题咨询
DeserializeFromStream<T> - Workarounds & Context Great catch — this behavior is definitely counterintuitive compared to most other .NET serializers, and it's easy to run into issues when you need to read additional data from the same stream after deserializing an initial object.
Why This Happens
Under the hood, JsonSerializer.DeserializeFromStream<T> uses a StreamReader that gets disposed when the method finishes. By default, disposing a StreamReader closes the underlying stream it's wrapping, which is the root cause of your stream being released unexpectedly.
How to Fix It
You have a couple of reliable workarounds to keep your stream open for subsequent reads:
Wrap Your Stream to Prevent Closure
Create a simple wrapper stream that overrides the close/dispose logic to leave the original stream intact:public class NonClosingStream : Stream { private readonly Stream _innerStream; public NonClosingStream(Stream innerStream) => _innerStream = innerStream; public override bool CanRead => _innerStream.CanRead; public override bool CanSeek => _innerStream.CanSeek; public override bool CanWrite => _innerStream.CanWrite; public override long Length => _innerStream.Length; public override long Position { get => _innerStream.Position; set => _innerStream.Position = value; } public override void Flush() => _innerStream.Flush(); public override int Read(byte[] buffer, int offset, int count) => _innerStream.Read(buffer, offset, count); public override long Seek(long offset, SeekOrigin origin) => _innerStream.Seek(offset, origin); public override void SetLength(long value) => _innerStream.SetLength(value); public override void Write(byte[] buffer, int offset, int count) => _innerStream.Write(buffer, offset, count); // Skip closing the inner stream public override void Close() { } protected override void Dispose(bool disposing) { } }Use it like this:
using var safeStream = new NonClosingStream(yourOriginalStream); var obj = JsonSerializer.DeserializeFromStream<YourType>(safeStream); // Now you can keep reading from yourOriginalStreamUse a Controlled
StreamReader
Instead of relying onDeserializeFromStream<T>, create your ownStreamReaderwith theleaveOpenflag set totrue, then use the overload that accepts a reader:using var reader = new StreamReader(yourOriginalStream, leaveOpen: true); var obj = JsonSerializer.Deserialize<YourType>(reader); // Original stream stays open for further operations
Additional Context
Since ServiceStack directs support to Stack Overflow (as you noted, they don't use GitHub issues for this), posting this scenario there could help highlight the issue for the team or other developers facing the same problem. Including details about your specific use case (reading multiple objects from a single stream) would make the request more concrete.
内容的提问来源于stack exchange,提问作者Alois Kraus

