繁体   English   中英

无法读取输入流

[英]Unable to read input stream

我在使用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/xmlapplication/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似乎已经解决了这个问题。 此链接还提供了更多的信息在这里

这是我在我的模型绑定器中执行的操作,但我不确定它如何与您的Action过滤器一起使用。 我在网上查了一下,有相互矛盾的信息; 有人说你无法读取输入流,因为它不可寻找,ASP.NET需要读取它来绑定模型。 有人说它确实可以搜索,并使用你上面分享的方法。 因此,找出真正有用的唯一方法就是测试。

我希望我的代码示例可以帮助您解决问题。

object request = null;
if (actionContext.Request.Method == HttpMethod.Post && "application/json".Equals(actionContext.Request.Content.Headers.ContentType.MediaType))
{
    var jsonContentTask = actionContext.Request.Content.ReadAsStringAsync();
    Task.WaitAll(jsonContentTask);
    string jsonContent = jsonContentTask.Result;
    //... other stuff
}

我可能错了,但这就是我发现的。 动作过滤器在模型绑定之后执行,这意味着已经读取了请求流。 在你的情况下,我不知道这意味着什么。 https://exceptionnotfound.net/the-asp-net-web-api-2-http-message-lifecycle-in-43-easy-steps-2/详细解释了生命周期。 更改内容类型不会更改生命周期事件,而是更改请求内容,这反过来可能会影响模型绑定。 如果您为该操作设置了模型,那么如何获取当前模型的操作过滤器应该有所帮助。 所以解决方案是从actionContext获取模型对象,然后相应地修改它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM