代码之家  ›  专栏  ›  技术社区  ›  User7291

无法读取输入流

  •  11
  • User7291  · 技术社区  · 6 年前

    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,它给出了以下错误:

    而输入流给出了这个错误

    context.Request.InputStream文件引发了类型为的异常System.InvalidOperationException异常系统IO流{System.InvalidOperationException异常}

    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 它给了我这个错误!!

    请告知!

    3 回复  |  直到 6 年前
        1
  •  3
  •   Gauravsa    6 年前

    有两点:

    首先,如果您尝试从流中读取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());
            }
         }
    

    maxRequestLength 在web.config文件似乎已经解决了这个问题。 here

        2
  •  2
  •   Sal    6 年前

    这是我如何在我的模型活页夹,但我不知道它将如何与您的行动过滤器工作。我在网上查了一下,发现有相互矛盾的信息;有人说你无法读取输入流,因为它不可查找并且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
    }
    
        3
  •  1
  •   Aamir Masood    6 年前

    我可能错了,但这是我的发现。动作过滤器在模型绑定之后执行,这意味着请求流已经被读取。对你来说,我不知道那是什么意思。 https://exceptionnotfound.net/the-asp-net-web-api-2-http-message-lifecycle-in-43-easy-steps-2/ 如果你有一个动作模型,那么 How to get current model in action filter 应该有帮助。所以解决方法是从 actionContext 然后相应地修改它。