【问题标题】:First request fails with HTTP 400 (Bad Request) after reading HttpRequest.InputStream读取 HttpRequest.InputStream 后,第一个请求失败并显示 HTTP 400(错误请求)
【发布时间】:2010-10-24 13:17:03
【问题描述】:

我开发了一个 asmx Web 服务(即 ASP.NET 2.0)。

有一段代码可以在处理 HTTP 请求(通过HttpContext.Current.Request.InputStream)时读取它的内容。我意识到 InputStream 对于一个请求可能只会被读取一次,并且我确保我不会尝试多次读取它。

问题似乎是,如果在应用程序生命周期的早期阶段(例如,在 pskill w3wp 之后,在 Application_Start 期间)读取了 InputStream,则 HTTP 请求失败并出现 HTTP 400 - Bad Request 错误,没有任何解释给定,没有抛出异常并且在 httperr 日志中没有条目。如果稍后读取它(例如在 web 方法本身中),无论 InputStream 是否被读取,请求都可以正常运行。如果没有读取 InputStream,Application_Start 运行良好。

这是某种 ASP.NET 错误吗? IIS错误?还是我敢于阅读 InputStream 做错了什么?如果是这样,是否有另一种方法可以在不干扰 IIS/ASP.NET 内部工作的情况下查看请求的“原始”内容?

简而言之,在 Application_Start 中添加此代码就足以重现此错误:

using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
    reader.ReadToEnd();

【问题讨论】:

  • 我认为您需要发布一些重现此问题的代码。不要发布你所有的代码,只需要人们运行和重现即可。
  • 您的建议迫使我进行更深入的调查。问题相应修改。谢谢!
  • 我不认为可以在 Application_Start 中调用 reader.RadToEnd,因为请求可能尚未完全收到。
  • 是的,这确实是我的猜测。我正在寻找一种在不干扰 ASP.NET 的情况下读取请求内容的方法。

标签: asp.net http iis


【解决方案1】:

在 Application_Start 期间无法找到在不干扰 ASP.NET/IIS 内部工作的情况下读取请求内容的方法。相反,最终确保在Application_Start 结束之前不会发生这种情况(并且从Application_End 开始的那一刻起也不会发生,这也被证明是有问题的并造成访问冲突)。

【讨论】:

    【解决方案2】:

    您不必使用 using bloc,因为这会关闭阅读器并因此关闭 httprequest 的输入流

    【讨论】:

      【解决方案3】:

      我建议不要Application_Start 期间尝试读取Request.InputStream - 它用于初始化应用程序。从 Application_Start 中访问请求对象会导致异常“请求在此上下文中不可用。”

      您想要读取输入流的事实表明您应该改用Application_BeginRequest - 这可以访问请求和响应

      总结:

      1. Application_Start
        应用程序启动时触发一次。虽然通常由第一个请求触发,但它发生在第一个请求设置之前。不要在这里请求特定代码,因为它无权访问请求和响应。

      2. Application_BeginRequest
        在调用任何页面处理程序之前为每个请求触发 - 您可以读取输入、写入响应、结束请求等...

      有关详细信息,请参阅这些 SO 文章:

      【讨论】:

        猜你喜欢
        • 2015-04-10
        • 2022-10-02
        • 1970-01-01
        • 2023-01-25
        • 2013-07-21
        • 2012-04-08
        • 1970-01-01
        • 2011-05-31
        • 2012-12-31
        相关资源
        最近更新 更多