c# - 无法读取输入流
问题描述
我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
它会给我这个错误!
请指教!
解决方案
有几点:
首先,如果您尝试从流中读取 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似乎已经解决了这个问题。此链接在此处进一步提供更多信息
推荐阅读
- rust - 是否可以声明 2 个相互依赖的静态可变变量?
- java - 在 Apache Flink 中手动更新状态的最佳方法是什么?
- php - POST 请求随机名称
- php - Laravel 的 Storage::Files 找不到我的文件
- python - 从股票数据框创建业务月末数据框
- android - 粘性服务被杀死并重新启动计划为 1000 毫秒,但从未重新启动
- google-apps-script - 如何启用对 FormApp 的权限?
- python - Python(多处理):如何将字典作为工作进程初始化函数的参数传递?
- c# - 将对象转换为 ArrayList
- swift - Swift:Firebase 分析 setScreenName