首页 > 解决方案 > 无法读取输入流

问题描述

ActionFilterAttribute用来在点击控制器之前获取请求,如下所示:

 public override void OnActionExecuting(HttpActionContext actionContext)
 {
     using (var stream = new MemoryStream())
     {
        HttpContextBase context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];
        context.Request.InputStream.Seek(0, SeekOrigin.Begin);
        context.Request.InputStream.CopyTo(stream);
        requestBody = Encoding.UTF8.GetString(stream.ToArray());
     }
 }

上述方法适用于小请求,但对于大型 json,它给了我这个错误:

在 HttpRequest.GetBufferedInputStream 的调用者填充内部存储之前访问了 BinaryRead、Form、Files 或 InputStream。

并且输入流给出了这个错误

context.Request.InputStream 抛出 System.InvalidOperationException System.IO.Stream {System.InvalidOperationException} 类型的异常

正如我在研究中发现的那样,超时是一个问题,但我无法更改代码中的超时。我尝试更改 web.config 文件中的值,maxRequestLength="102400000"maxAllowedContentLength="209715100"我仍然面临同样的错误。
如果我阅读GetBufferedInputStream但仍然相同的问题,它只是读取缓冲区的一部分,而不是整个流。

我还尝试了以下方法:

 Stream InStream;
 int Len;
 InStream = HttpContext.Current.Request.InputStream;
 Len = System.Convert.ToInt32(InStream.Length);
 byte[] ByteArray = new byte[Len + 1];
 InStream.Seek(0, SeekOrigin.Begin);
 InStream.Read(ByteArray, 0, Len);
 var jsonParam = System.Text.Encoding.UTF8.GetString(ByteArray); 

请注意,如果我设置了内容类型application/xml或者application/x-www-form-urlencoded它可以工作,但如果我将它设置为application/json它会给我这个错误!

请指教!

标签: c#asp.net-web-api2inputstreammemorystream

解决方案


有几点:

首先,如果您尝试从流中读取 0 个字节,那么它将引发 System.InvalidOperationException 异常。因此,我将更改您的代码,如下所示,并添加检查ContentLength > 0.

using (var stream = new MemoryStream())
     {
        HttpContextBase context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];
        if(context.Request.Contentlength > 0)
        {
            context.Request.InputStream.Seek(0, SeekOrigin.Begin);
            context.Request.InputStream.CopyTo(stream);
            requestBody = Encoding.UTF8.GetString(stream.ToArray());
        }
     }

另外,我曾经遇到过同样的问题,增加 web.config 中的maxRequestLength似乎已经解决了这个问题。此链接在此处进一步提供更多信息


推荐阅读