Asp.net
倒帶請求正文流
我正在重新實現一個請求記錄器作為 Owin 中間件,它記錄所有傳入請求的請求 url 和正文。我能夠讀取正文,但如果我這樣做,我的控制器中的正文參數為空。
我猜它是空的,因為流位置在末尾,所以當它試圖反序列化主體時,沒有什麼可讀取的了。我在以前版本的 Web API 中遇到了類似的問題,但能夠將 Stream 位置設置回 0。這個特定的流會引發
This stream does not support seek operations異常。在最新版本的 Web API 2.0 中,我可以
Request.HttpContent.ReadAsStringAsync()在我的請求記錄器中呼叫,並且主體仍會完整地到達控制器。閱讀後如何回退流?
要麼
如何在不使用請求正文的情況下讀取它?
public class RequestLoggerMiddleware : OwinMiddleware { public RequestLoggerMiddleware(OwinMiddleware next) : base(next) { } public override Task Invoke(IOwinContext context) { return Task.Run(() => { string body = new StreamReader(context.Request.Body).ReadToEnd(); // log body context.Request.Body.Position = 0; // cannot set stream position back to 0 Console.WriteLine(context.Request.Body.CanSeek); // prints false this.Next.Invoke(context); }); } }public class SampleController : ApiController { public void Post(ModelClass body) { // body is now null if the middleware reads it } }
剛剛找到一個解決方案。用包含數據的新流替換原始流。
public override async Task Invoke(IOwinContext context) { return Task.Run(() => { string body = new StreamReader(context.Request.Body).ReadToEnd(); // log body byte[] requestData = Encoding.UTF8.GetBytes(body); context.Request.Body = new MemoryStream(requestData); await this.Next.Invoke(context); }); }如果您正在處理大量數據,我相信 a
FileStream也可以作為替代品。