如何在ASP.NET中获取原始请求主体?

Jos*_* M. 31 asp.net http

在这种情况HttpApplication.BeginRequest下,我如何阅读整个原始请求体?当我尝试读取它时InputStream长度为0,这让我相信它可能已经被ASP.NET读过了.

我试过像这样读取InputStream:

using (StreamReader reader = new StreamReader(context.Request.InputStream))
{
    string text = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)

但我得到的只是一个空字符串.我已经将位置重置为0,但当然一旦读取了它,它就会消失,所以这样做不起作用.最后,检查流的长度返回0.

编辑:这是针对POST请求的.

Pål*_*gbø 18

BeginRequest事件中未填充请求对象.您需要稍后在事件生命周期中访问此对象,例如Init,Load或PreRender.此外,您可能希望将输入流复制到内存流,因此您可以使用seek:

protected void Page_Load(object sender, EventArgs e)
{
    MemoryStream memstream = new MemoryStream();
    Request.InputStream.CopyTo(memstream);
    memstream.Position = 0;
    using (StreamReader reader = new StreamReader(memstream))
    {
        string text = reader.ReadToEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)


Ian*_*Ian 10

Pål的答案是正确的,但也可以做得更短:

string req_txt;
using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
{
    req_txt = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)

这是.NET 4.6.

  • 这将关闭当前编写的InputStream,稍后将在ASP.NET管道中引发异常。帕尔的答案通过制作副本避免了这种陷阱。如果您只是删除“ using”语句,您的答案将起作用。 (3认同)

小智 5

在 ASP.NET Core 2 中:

using (var reader = new StreamReader(HttpContext.Request.Body)) {
    var body = reader.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)


Jos*_* M. -9

这就是我最终所做的:

//Save the request content. (Unfortunately it can't be written to a stream directly.)
context.Request.SaveAs(filePath, false);
Run Code Online (Sandbox Code Playgroud)

  • 你不应该使用这种方式,随着请求数量的增加,太多的IO操作会给你带来麻烦。读取 Request.InputStream 并将 Position 设置为 0 最后有效。 (3认同)
  • @sahs - 你能推荐一个更好的选择吗?这个方法是最后的努力。 (2认同)