简体   繁体   English

为什么我不能两次读取Http Request Input流?

[英]Why can't I read Http Request Input stream twice?

I was putting in some debugging code to test some things, and then the debug code didn't behave as expected. 我正在添加一些调试代码来测试一些东西,然后调试代码没有按预期运行。 The example below is a simplified code to demonstrate my question. 以下示例是用于演示我的问题的简化代码。

This is in .NET 4 and using WebApi, I'm trying to print out the body of the http request in the debug code. 这是在.NET 4中并使用WebApi,我试图在调试代码中打印出http请求的主体。 To do this I seek the Input stream back and read the stream. 为此,我寻找输入流并读取流。 It works fine the first time, but if I try to read it again, I get an empty string. 它第一次工作正常,但如果我再次尝试读取它,我会得到一个空字符串。

Why can't I seek back and read the InputStream a second time? 为什么我不能再次寻找并读取InputStream? In the example below, body2 is always empty. 在下面的示例中,body2始终为空。 In the second set, CanSeek is still true and the the second call to ReadToEnd() returns an empty string overwriting the default. 在第二组中,CanSeek仍为true,第二次调用ReadToEnd()会返回一个空字符串,覆盖默认值。

using System.IO;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

public class TestController : ApiController
{

    public class TestOutuput
    {
        public string firstRead;
        public string secondRead;
    }

    public HttpResponseMessage Post()
    {
        string body1 = "default for one";
        string body2 = "default for two";
        if (HttpContext.Current.Request.InputStream.CanSeek)
        {
            HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
        }
        using (var reader = new StreamReader(HttpContext.Current.Request.InputStream))
        {
            body1 = reader.ReadToEnd();
        }

        if (HttpContext.Current.Request.InputStream.CanSeek)
        {
            HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
        }
        using (var reader2 = new StreamReader(HttpContext.Current.Request.InputStream))
        {
            // this is always empty, even after seek back to origin
            body2 = reader2.ReadToEnd();
        }

        TestOutuput testOutput = new TestOutuput() { firstRead = body1, secondRead = body2 };
        HttpResponseMessage response = new HttpResponseMessage();
        return Request.CreateResponse<TestOutuput>(HttpStatusCode.OK, testOutput);
    }
}

StreamReader calls Dispose on given stream when disposed. StreamReader Dispose时调用给定流上的Dispose To leave the stream open use the appropriate constructor for the StreamReader . 要使流保持打开状态,请使用StreamReader相应构造函数 Or better yet, just copy it to a buffer. 或者更好的是,只需将其复制到缓冲区即可。 From MSDN: 来自MSDN:

When reading from a Stream, it is more efficient to use a buffer that is the same size as the internal buffer of the stream. 从Stream读取时,使用与流的内部缓冲区大小相同的缓冲区更有效。

See this question for example. 例如,请参阅此问题

HttpContext.Current.Request.InputStream.Position=0;

Once you read the position goes to last value, from there its trying to read second time. 一旦你读到位置转到最后一个值,从那里它试图第二次读取。 So before you read, set the position to zero. 所以在阅读之前,将位置设置为零。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM