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

时间:2014-02-23 17:09:33

标签: c# .net asp.net-mvc asp.net-web-api

我正在调试一些调试代码来测试一些东西,然后调试代码没有按预期运行。以下示例是用于演示我的问题的简化代码。

这是在.NET 4中使用WebApi,我试图在调试代码中打印出http请求的主体。为此,我寻找输入流并读取流。它第一次工作正常,但如果我再次尝试读取它,我会得到一个空字符串。

为什么我不能再次寻找和读取InputStream?在下面的示例中,body2始终为空。在第二个集合中,CanSeek仍然为真,第二次调用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);
    }
}

2 个答案:

答案 0 :(得分:21)

处置时,

StreamReader在给定流上调用Dispose。要使流保持打开状态,请使用StreamReader作为{{1}}。 或者更好的是,只需将其复制到缓冲区即可。来自MSDN:

  

从Stream中读取时,使用缓冲区更有效   与流的内部缓冲区大小相同。

例如,请参阅appropriate constructor

答案 1 :(得分:6)

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

一旦你读到位置转到最后一个值,从那里它试图第二次读取。 所以在你阅读之前,将位置设置为零。

希望它有所帮助。