Asp.net-Core
讀取請求正文兩次
我正在嘗試讀取中間件中的主體以進行身份驗證,但是當請求到達 api 控制器時,對象為空,因為主體已被讀取。有沒有辦法解決。我正在我的中間件中讀取這樣的正文。
var buffer = new byte[ Convert.ToInt32( context.Request.ContentLength ) ]; await context.Request.Body.ReadAsync( buffer, 0, buffer.Length ); var body = Encoding.UTF8.GetString( buffer );
如果您使用
application/x-www-form-urlencodedormultipart/form-data,您可以安全地context.Request.ReadFormAsync()多次呼叫,因為它會在後續呼叫中返回一個記憶體的實例。如果您使用不同的內容類型,則必須手動緩衝請求並將請求正文替換為可重繞的流,例如
MemoryStream. 以下是使用內聯中間件的方法(您需要盡快在管道中註冊它):app.Use(next => async context => { // Keep the original stream in a separate // variable to restore it later if necessary. var stream = context.Request.Body; // Optimization: don't buffer the request if // there was no stream or if it is rewindable. if (stream == Stream.Null || stream.CanSeek) { await next(context); return; } try { using (var buffer = new MemoryStream()) { // Copy the request stream to the memory stream. await stream.CopyToAsync(buffer); // Rewind the memory stream. buffer.Position = 0L; // Replace the request stream by the memory stream. context.Request.Body = buffer; // Invoke the rest of the pipeline. await next(context); } } finally { // Restore the original stream. context.Request.Body = stream; } });您還可以使用
BufferingHelper.EnableRewind()擴展,它是Microsoft.AspNet.Http包的一部分:它基於類似的方法,但依賴於一個特殊的流,該流開始在記憶體中緩衝數據,並在達到門檻值時將所有內容假離線到磁碟上的臨時文件:app.Use(next => context => { context.Request.EnableRewind(); return next(context); });僅供參考:未來可能會在 vNext 中添加緩衝中間件。