【发布时间】:2022-01-11 20:06:27
【问题描述】:
我正在使用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 它会给我这个错误!!
请指教!
【问题讨论】:
-
您是否尝试使用DelegatingHandler 来获取请求正文?大json的大小是多少?我用 195077 个字符的 json 尝试了你的第一个变体,它工作正常
-
嗯,只有一个输入流,而您正在读取它,因此 ASP.NET 无法完成它的工作。该流通常是转发/只读的,您不能多次查找和读取它。为什么要阅读该流? ASP.NET 应该读取它,然后您使用 ASP.NET 功能来做您必须做的事情
-
@SimonMourier 因为请求是加密的,所以我需要对其进行解密,然后将其作为 json 传递给控制器
-
@Albert 您发送的 json 内容类型为
application/json吗?因为如果我发送它application/x-www-form-urlencoded它可以工作 -
你有为动作定义的模型吗?
标签: c# asp.net-web-api2 inputstream memorystream